aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/Makefile4
-rw-r--r--sys/amd64/amd64/elf_machdep.c1
-rw-r--r--sys/amd64/amd64/gdb_machdep.c4
-rw-r--r--sys/amd64/amd64/initcpu.c1
-rw-r--r--sys/amd64/amd64/machdep.c4
-rw-r--r--sys/amd64/amd64/pmap.c9
-rw-r--r--sys/amd64/amd64/trap.c14
-rw-r--r--sys/amd64/amd64/vm_machdep.c2
-rw-r--r--sys/amd64/conf/NOTES17
-rw-r--r--sys/amd64/ia32/ia32_reg.c6
-rw-r--r--sys/amd64/ia32/ia32_signal.c12
-rw-r--r--sys/amd64/include/md_var.h1
-rw-r--r--sys/amd64/include/vmm.h26
-rw-r--r--sys/amd64/include/vmparam.h5
-rw-r--r--sys/amd64/linux/Makefile17
-rw-r--r--sys/amd64/linux/linux.h549
-rw-r--r--sys/amd64/linux/linux_dummy.c141
-rw-r--r--sys/amd64/linux/linux_genassym.c15
-rw-r--r--sys/amd64/linux/linux_ipc64.h142
-rw-r--r--sys/amd64/linux/linux_locore.s76
-rw-r--r--sys/amd64/linux/linux_machdep.c433
-rw-r--r--sys/amd64/linux/linux_proto.h1663
-rw-r--r--sys/amd64/linux/linux_support.s124
-rw-r--r--sys/amd64/linux/linux_syscall.h310
-rw-r--r--sys/amd64/linux/linux_syscalls.c325
-rw-r--r--sys/amd64/linux/linux_sysent.c335
-rw-r--r--sys/amd64/linux/linux_systrace_args.c6885
-rw-r--r--sys/amd64/linux/linux_sysvec.c946
-rw-r--r--sys/amd64/linux/linux_vdso.lds.s69
-rw-r--r--sys/amd64/linux/syscalls.conf11
-rw-r--r--sys/amd64/linux/syscalls.master515
-rw-r--r--sys/amd64/linux32/linux.h139
-rw-r--r--sys/amd64/linux32/linux32_dummy.c20
-rw-r--r--sys/amd64/linux32/linux32_genassym.c4
-rw-r--r--sys/amd64/linux32/linux32_locore.s158
-rw-r--r--sys/amd64/linux32/linux32_machdep.c130
-rw-r--r--sys/amd64/linux32/linux32_proto.h110
-rw-r--r--sys/amd64/linux32/linux32_syscall.h10
-rw-r--r--sys/amd64/linux32/linux32_syscalls.c9
-rw-r--r--sys/amd64/linux32/linux32_sysent.c45
-rw-r--r--sys/amd64/linux32/linux32_systrace_args.c474
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c201
-rw-r--r--sys/amd64/linux32/linux32_vdso.lds.s66
-rw-r--r--sys/amd64/linux32/syscalls.master71
-rw-r--r--sys/amd64/vmm/amd/svm.c27
-rw-r--r--sys/amd64/vmm/intel/vmx.c37
-rw-r--r--sys/amd64/vmm/intel/vmx.h2
-rw-r--r--sys/amd64/vmm/intel/vmx_msr.c3
-rw-r--r--sys/amd64/vmm/vmm.c114
-rw-r--r--sys/amd64/vmm/vmm_instruction_emul.c2
-rw-r--r--sys/amd64/vmm/vmm_stat.c1
-rw-r--r--sys/amd64/vmm/vmm_stat.h1
-rw-r--r--sys/arm/arm/bcopyinout.S9
-rw-r--r--sys/arm/arm/bcopyinout_xscale.S12
-rw-r--r--sys/arm/arm/blockio.S6
-rw-r--r--sys/arm/arm/bus_space_base.c16
-rw-r--r--sys/arm/arm/busdma_machdep-v6.c44
-rw-r--r--sys/arm/arm/busdma_machdep.c26
-rw-r--r--sys/arm/arm/copystr.S5
-rw-r--r--sys/arm/arm/cpu_asm-v6.S72
-rw-r--r--sys/arm/arm/cpufunc.c142
-rw-r--r--sys/arm/arm/cpufunc_asm_arm11x6.S40
-rw-r--r--sys/arm/arm/cpufunc_asm_arm9.S4
-rw-r--r--sys/arm/arm/cpufunc_asm_armv6.S6
-rw-r--r--sys/arm/arm/cpufunc_asm_armv7.S2
-rw-r--r--sys/arm/arm/cpufunc_asm_xscale_c3.S4
-rw-r--r--sys/arm/arm/cpuinfo.c8
-rw-r--r--sys/arm/arm/db_interface.c3
-rw-r--r--sys/arm/arm/elf_machdep.c1
-rw-r--r--sys/arm/arm/elf_trampoline.c27
-rw-r--r--sys/arm/arm/exception.S37
-rw-r--r--sys/arm/arm/fiq.c2
-rw-r--r--sys/arm/arm/fusu.S6
-rw-r--r--sys/arm/arm/genassym.c6
-rw-r--r--sys/arm/arm/generic_timer.c112
-rw-r--r--sys/arm/arm/gic.c4
-rw-r--r--sys/arm/arm/intr.c4
-rw-r--r--sys/arm/arm/locore-v4.S3
-rw-r--r--sys/arm/arm/machdep.c168
-rw-r--r--sys/arm/arm/mp_machdep.c6
-rw-r--r--sys/arm/arm/mpcore_timer.c4
-rw-r--r--sys/arm/arm/nexus.c4
-rw-r--r--sys/arm/arm/physmem.c2
-rw-r--r--sys/arm/arm/pl190.c8
-rw-r--r--sys/arm/arm/pl310.c30
-rw-r--r--sys/arm/arm/pmap-v6-new.c7
-rw-r--r--sys/arm/arm/pmap-v6.c38
-rw-r--r--sys/arm/arm/pmap.c70
-rw-r--r--sys/arm/arm/stack_machdep.c10
-rw-r--r--sys/arm/arm/support.S4
-rw-r--r--sys/arm/arm/swtch.S34
-rw-r--r--sys/arm/arm/sys_machdep.c82
-rw-r--r--sys/arm/arm/trap-v6.c25
-rw-r--r--sys/arm/arm/trap.c15
-rw-r--r--sys/arm/arm/vfp.c4
-rw-r--r--sys/arm/arm/vm_machdep.c24
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_sdhci.c18
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_spi.c25
-rw-r--r--sys/arm/conf/ALPINE2
-rw-r--r--sys/arm/conf/BEAGLEBONE2
-rw-r--r--sys/arm/conf/CUBIEBOARD2
-rw-r--r--sys/arm/conf/CUBIEBOARD22
-rw-r--r--sys/arm/conf/DOCKSTAR1
-rw-r--r--sys/arm/conf/DREAMPLUG-10011
-rw-r--r--sys/arm/conf/EFIKA_MX2
-rw-r--r--sys/arm/conf/EXYNOS5.common2
-rw-r--r--sys/arm/conf/NOTES23
-rw-r--r--sys/arm/conf/PANDABOARD2
-rw-r--r--sys/arm/conf/RK31882
-rw-r--r--sys/arm/conf/RPI-B1
-rw-r--r--sys/arm/conf/RPI21
-rw-r--r--sys/arm/conf/SOCKIT.common2
-rw-r--r--sys/arm/conf/VIRT6
-rw-r--r--sys/arm/conf/VYBRID2
-rw-r--r--sys/arm/conf/YYHD1826
-rw-r--r--sys/arm/conf/ZEDBOARD2
-rw-r--r--sys/arm/freescale/imx/imx6_sdma.c1
-rw-r--r--sys/arm/include/_types.h6
-rw-r--r--sys/arm/include/asm.h2
-rw-r--r--sys/arm/include/cpu-v6.h13
-rw-r--r--sys/arm/include/pcpu.h9
-rw-r--r--sys/arm/include/proc.h4
-rw-r--r--sys/arm/include/sysreg.h2
-rw-r--r--sys/arm/include/vmparam.h5
-rw-r--r--sys/arm/qemu/files.qemu3
-rw-r--r--sys/arm/qemu/virt_mp.c119
-rw-r--r--sys/arm/ti/am335x/am335x_lcd.c4
-rw-r--r--sys/arm/ti/am335x/am335x_pmic.c154
-rw-r--r--sys/arm/ti/am335x/tps65217x.h114
-rw-r--r--sys/arm64/acpica/OsdEnvironment.c76
-rw-r--r--sys/arm64/acpica/acpi_machdep.c217
-rw-r--r--sys/arm64/acpica/acpi_wakeup.c61
-rw-r--r--sys/arm64/arm64/db_interface.c4
-rw-r--r--sys/arm64/arm64/db_trace.c25
-rw-r--r--sys/arm64/arm64/exception.S21
-rw-r--r--sys/arm64/arm64/gic.c58
-rw-r--r--sys/arm64/arm64/gic.h54
-rw-r--r--sys/arm64/arm64/gic_acpi.c161
-rw-r--r--sys/arm64/arm64/gic_fdt.c87
-rw-r--r--sys/arm64/arm64/machdep.c2
-rw-r--r--sys/arm64/arm64/nexus.c166
-rw-r--r--sys/arm64/arm64/unwind.c52
-rw-r--r--sys/arm64/arm64/vfp.c2
-rw-r--r--sys/arm64/conf/GENERIC1
-rw-r--r--sys/arm64/include/acpica_machdep.h55
-rw-r--r--sys/arm64/include/atomic.h28
-rw-r--r--sys/arm64/include/iodev.h65
-rw-r--r--sys/arm64/include/pci_cfgreg.h1
-rw-r--r--sys/arm64/include/pcpu.h3
-rw-r--r--sys/arm64/include/stack.h8
-rw-r--r--sys/arm64/include/vmparam.h5
-rw-r--r--sys/boot/efi/libefi/Makefile.depend1
-rw-r--r--sys/boot/efi/loader/arch/arm64/exec.c40
-rw-r--r--sys/boot/fdt/dts/arm/meson3.dtsi77
-rw-r--r--sys/boot/fdt/dts/arm/sun4i-a10.dtsi1
-rw-r--r--sys/boot/fdt/dts/arm/sun7i-a20.dtsi1
-rw-r--r--sys/boot/fdt/dts/arm/vsatv102-m6.dts11
-rw-r--r--sys/boot/fdt/dts/arm/yyhd18-m3.dts237
-rw-r--r--sys/boot/ficl/Makefile.depend1
-rw-r--r--sys/boot/forth/support.4th6
-rw-r--r--sys/boot/i386/boot0/Makefile.depend1
-rw-r--r--sys/boot/i386/boot0sio/Makefile.depend1
-rw-r--r--sys/boot/i386/boot2/Makefile.depend1
-rw-r--r--sys/boot/i386/loader/Makefile.depend1
-rw-r--r--sys/boot/i386/zfsloader/Makefile.depend1
-rw-r--r--sys/boot/uboot/lib/module.c4
-rw-r--r--sys/boot/userboot/userboot/conf.c3
-rw-r--r--sys/boot/zfs/zfsimpl.c4
-rw-r--r--sys/cam/cam.c50
-rw-r--r--sys/cam/cam.h12
-rw-r--r--sys/cam/ctl/ctl.c4
-rw-r--r--sys/cam/ctl/scsi_ctl.c18
-rw-r--r--sys/cam/scsi/scsi_all.c892
-rw-r--r--sys/cam/scsi/scsi_all.h283
-rw-r--r--sys/cddl/compat/opensolaris/sys/nvpair.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c14
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c5
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c18
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c1
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c28
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c33
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c24
-rw-r--r--sys/cddl/dev/dtrace/amd64/dtrace_asm.S2
-rw-r--r--sys/cddl/dev/dtrace/arm/dtrace_asm.S1
-rw-r--r--sys/cddl/dev/dtrace/i386/dtrace_asm.S2
-rw-r--r--sys/compat/ia32/ia32_sysvec.c1
-rw-r--r--sys/compat/linprocfs/linprocfs.c177
-rw-r--r--sys/compat/linsysfs/linsysfs.c10
-rw-r--r--sys/compat/linux/check_error.d4
-rw-r--r--sys/compat/linux/check_internal_locks.d35
-rw-r--r--sys/compat/linux/linux.c205
-rw-r--r--sys/compat/linux/linux.h95
-rw-r--r--sys/compat/linux/linux_common.c93
-rw-r--r--sys/compat/linux/linux_emul.c512
-rw-r--r--sys/compat/linux/linux_emul.h92
-rw-r--r--sys/compat/linux/linux_event.c890
-rw-r--r--sys/compat/linux/linux_event.h60
-rw-r--r--sys/compat/linux/linux_file.c75
-rw-r--r--sys/compat/linux/linux_file.h71
-rw-r--r--sys/compat/linux/linux_fork.c304
-rw-r--r--sys/compat/linux/linux_futex.c212
-rw-r--r--sys/compat/linux/linux_futex.h3
-rw-r--r--sys/compat/linux/linux_getcwd.c4
-rw-r--r--sys/compat/linux/linux_ioctl.c59
-rw-r--r--sys/compat/linux/linux_ioctl.h13
-rw-r--r--sys/compat/linux/linux_ipc.c10
-rw-r--r--sys/compat/linux/linux_ipc.h4
-rw-r--r--sys/compat/linux/linux_mib.c366
-rw-r--r--sys/compat/linux/linux_mib.h19
-rw-r--r--sys/compat/linux/linux_misc.c824
-rw-r--r--sys/compat/linux/linux_misc.h42
-rw-r--r--sys/compat/linux/linux_signal.c348
-rw-r--r--sys/compat/linux/linux_signal.h26
-rw-r--r--sys/compat/linux/linux_socket.c524
-rw-r--r--sys/compat/linux/linux_socket.h155
-rw-r--r--sys/compat/linux/linux_stats.c107
-rw-r--r--sys/compat/linux/linux_sysctl.c8
-rw-r--r--sys/compat/linux/linux_time.c277
-rw-r--r--sys/compat/linux/linux_timer.c27
-rw-r--r--sys/compat/linux/linux_timer.h23
-rw-r--r--sys/compat/linux/linux_uid16.c10
-rw-r--r--sys/compat/linux/linux_util.c115
-rw-r--r--sys/compat/linux/linux_util.h6
-rw-r--r--sys/compat/linux/linux_vdso.c244
-rw-r--r--sys/compat/linux/linux_vdso.h65
-rw-r--r--sys/compat/linux/stats_timing.d1
-rw-r--r--sys/compat/svr4/imgact_svr4.c2
-rw-r--r--sys/compat/svr4/svr4_misc.c20
-rw-r--r--sys/compat/svr4/svr4_resource.c16
-rw-r--r--sys/compat/svr4/svr4_sysvec.c1
-rw-r--r--sys/conf/NOTES5
-rw-r--r--sys/conf/files58
-rw-r--r--sys/conf/files.amd64102
-rw-r--r--sys/conf/files.arm5
-rw-r--r--sys/conf/files.arm648
-rw-r--r--sys/conf/files.i38624
-rw-r--r--sys/conf/files.pc9817
-rw-r--r--sys/conf/files.powerpc7
-rw-r--r--sys/conf/kern.post.mk20
-rw-r--r--sys/conf/kern.pre.mk25
-rw-r--r--sys/conf/kmod.mk2
-rw-r--r--sys/conf/options4
-rw-r--r--sys/conf/options.arm1
-rw-r--r--sys/contrib/dev/acpica/common/ahuuids.c76
-rw-r--r--sys/contrib/dev/acpica/include/acuuid.h44
-rw-r--r--sys/dev/acpi_support/acpi_ibm.c65
-rw-r--r--sys/dev/acpica/Osd/OsdHardware.c10
-rw-r--r--sys/dev/acpica/acpi_cpu.c18
-rw-r--r--sys/dev/ahci/ahci.h2
-rw-r--r--sys/dev/aic7xxx/aic79xx_pci.c14
-rw-r--r--sys/dev/ath/ath_rate/sample/sample.c13
-rw-r--r--sys/dev/ath/if_ath.c172
-rw-r--r--sys/dev/ath/if_ath_rx.c8
-rw-r--r--sys/dev/ath/if_ath_rx.h3
-rw-r--r--sys/dev/ath/if_ath_tdma.c2
-rw-r--r--sys/dev/ath/if_ath_tx.c4
-rw-r--r--sys/dev/ath/if_athvar.h3
-rw-r--r--sys/dev/atkbdc/psm.c121
-rw-r--r--sys/dev/bwi/bwimac.c57
-rw-r--r--sys/dev/bwi/bwimac.h1
-rw-r--r--sys/dev/bwi/if_bwi.c35
-rw-r--r--sys/dev/bwi/if_bwi_pci.c20
-rw-r--r--sys/dev/bwn/if_bwn.c21
-rw-r--r--sys/dev/bxe/bxe.c118
-rw-r--r--sys/dev/bxe/bxe.h6
-rw-r--r--sys/dev/bxe/ecore_reg.h1
-rw-r--r--sys/dev/cxgbe/t4_main.c22
-rw-r--r--sys/dev/cxgbe/t4_netmap.c2
-rw-r--r--sys/dev/cxgbe/t4_sge.c2
-rw-r--r--sys/dev/drm/drmP.h10
-rw-r--r--sys/dev/drm/drm_agpsupport.c35
-rw-r--r--sys/dev/drm/drm_bufs.c10
-rw-r--r--sys/dev/drm/drm_drv.c22
-rw-r--r--sys/dev/drm/drm_irq.c6
-rw-r--r--sys/dev/drm/i915_drv.c8
-rw-r--r--sys/dev/drm/mach64_drv.c4
-rw-r--r--sys/dev/drm/mga_drv.c8
-rw-r--r--sys/dev/drm/r128_drv.c4
-rw-r--r--sys/dev/drm/radeon_drv.c4
-rw-r--r--sys/dev/drm/savage_drv.c4
-rw-r--r--sys/dev/drm/sis_drv.c4
-rw-r--r--sys/dev/drm/tdfx_drv.c4
-rw-r--r--sys/dev/drm2/drm_bufs.c4
-rw-r--r--sys/dev/drm2/i915/i915_gem.c5
-rw-r--r--sys/dev/dwc/if_dwc.c7
-rw-r--r--sys/dev/e1000/e1000_defines.h2
-rw-r--r--sys/dev/e1000/if_em.c702
-rw-r--r--sys/dev/e1000/if_em.h58
-rw-r--r--sys/dev/fdt/fdt_common.c17
-rw-r--r--sys/dev/fdt/fdt_common.h1
-rw-r--r--sys/dev/gpio/gpioled.c27
-rw-r--r--sys/dev/hwpmc/hwpmc_armv7.c90
-rw-r--r--sys/dev/hwpmc/hwpmc_armv7.h5
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c6
-rw-r--r--sys/dev/hwpmc/pmc_events.h369
-rw-r--r--sys/dev/ichiic/ig4_iic.c966
-rw-r--r--sys/dev/ichiic/ig4_pci.c192
-rw-r--r--sys/dev/ichiic/ig4_reg.h622
-rw-r--r--sys/dev/ichiic/ig4_var.h96
-rw-r--r--sys/dev/ichsmb/ichsmb_pci.c8
-rw-r--r--sys/dev/if_ndis/if_ndis.c12
-rw-r--r--sys/dev/ipw/if_ipw.c9
-rw-r--r--sys/dev/iwi/if_iwi.c14
-rw-r--r--sys/dev/iwn/if_iwn.c35
-rw-r--r--sys/dev/ixgbe/if_ix.c1128
-rw-r--r--sys/dev/ixgbe/if_ixv.c92
-rw-r--r--sys/dev/ixgbe/ix_txrx.c33
-rw-r--r--sys/dev/ixgbe/ixgbe.h221
-rw-r--r--sys/dev/ixgbe/ixgbe_mbx.h27
-rw-r--r--sys/dev/ixgbe/ixgbe_vf.c57
-rw-r--r--sys/dev/ixl/i40e_adminq.c62
-rw-r--r--sys/dev/ixl/i40e_adminq.h3
-rw-r--r--sys/dev/ixl/i40e_adminq_cmd.h123
-rw-r--r--sys/dev/ixl/i40e_common.c653
-rw-r--r--sys/dev/ixl/i40e_devids.h68
-rw-r--r--sys/dev/ixl/i40e_hmc.c69
-rw-r--r--sys/dev/ixl/i40e_hmc.h12
-rw-r--r--sys/dev/ixl/i40e_lan_hmc.c29
-rw-r--r--sys/dev/ixl/i40e_nvm.c53
-rw-r--r--sys/dev/ixl/i40e_osdep.h10
-rw-r--r--sys/dev/ixl/i40e_prototype.h32
-rw-r--r--sys/dev/ixl/i40e_register.h1941
-rw-r--r--sys/dev/ixl/i40e_type.h201
-rw-r--r--sys/dev/ixl/i40e_virtchnl.h21
-rw-r--r--sys/dev/ixl/if_ixl.c189
-rw-r--r--sys/dev/ixl/if_ixlv.c36
-rw-r--r--sys/dev/ixl/ixl.h1
-rw-r--r--sys/dev/ixl/ixlv.h1
-rw-r--r--sys/dev/ixl/ixlvc.c20
-rw-r--r--sys/dev/led/led.c3
-rw-r--r--sys/dev/malo/if_malo.c11
-rw-r--r--sys/dev/mfi/mfi.c4
-rw-r--r--sys/dev/mmc/mmcsd.c25
-rw-r--r--sys/dev/mpr/mpi/mpi2.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_cnfg.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_hbd.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_history.txt8
-rw-r--r--sys/dev/mpr/mpi/mpi2_init.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_ioc.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_ra.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_raid.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_sas.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_targ.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_tool.h8
-rw-r--r--sys/dev/mpr/mpi/mpi2_type.h8
-rw-r--r--sys/dev/mpr/mpr.c90
-rw-r--r--sys/dev/mpr/mpr_config.c5
-rw-r--r--sys/dev/mpr/mpr_ioctl.h7
-rw-r--r--sys/dev/mpr/mpr_mapping.c72
-rw-r--r--sys/dev/mpr/mpr_mapping.h10
-rw-r--r--sys/dev/mpr/mpr_pci.c14
-rw-r--r--sys/dev/mpr/mpr_sas.c476
-rw-r--r--sys/dev/mpr/mpr_sas.h31
-rw-r--r--sys/dev/mpr/mpr_sas_lsi.c362
-rw-r--r--sys/dev/mpr/mpr_user.c41
-rw-r--r--sys/dev/mpr/mprvar.h38
-rw-r--r--sys/dev/mwl/if_mwl.c28
-rw-r--r--sys/dev/nand/nfc_rb.c12
-rw-r--r--sys/dev/netmap/if_em_netmap.h2
-rw-r--r--sys/dev/ofw/ofw_bus_subr.c22
-rw-r--r--sys/dev/ofw/ofw_bus_subr.h3
-rw-r--r--sys/dev/pci/pci.c14
-rw-r--r--sys/dev/pci/pci_host_generic.c626
-rw-r--r--sys/dev/pci/pci_if.m17
-rw-r--r--sys/dev/pci/pci_iov.c14
-rw-r--r--sys/dev/pci/pci_iov.h49
-rw-r--r--sys/dev/pci/pci_iov_if.m52
-rw-r--r--sys/dev/pci/pcivar.h15
-rw-r--r--sys/dev/pci/vga_pci.c7
-rw-r--r--sys/dev/proto/proto.h6
-rw-r--r--sys/dev/proto/proto_bus_pci.c20
-rw-r--r--sys/dev/proto/proto_busdma.c301
-rw-r--r--sys/dev/proto/proto_busdma.h75
-rw-r--r--sys/dev/proto/proto_core.c96
-rw-r--r--sys/dev/proto/proto_dev.h35
-rw-r--r--sys/dev/psci/psci.c57
-rw-r--r--sys/dev/ral/rt2560.c25
-rw-r--r--sys/dev/ral/rt2661.c23
-rw-r--r--sys/dev/ral/rt2860.c19
-rw-r--r--sys/dev/sfxge/common/ef10_tlv_layout.h691
-rw-r--r--sys/dev/sfxge/common/efsys.h114
-rw-r--r--sys/dev/sfxge/common/efx.h909
-rw-r--r--sys/dev/sfxge/common/efx_bootcfg.c45
-rw-r--r--sys/dev/sfxge/common/efx_check.h388
-rw-r--r--sys/dev/sfxge/common/efx_crc32.c127
-rw-r--r--sys/dev/sfxge/common/efx_ev.c686
-rw-r--r--sys/dev/sfxge/common/efx_filter.c1722
-rw-r--r--sys/dev/sfxge/common/efx_hash.c333
-rw-r--r--sys/dev/sfxge/common/efx_impl.h659
-rw-r--r--sys/dev/sfxge/common/efx_intr.c436
-rw-r--r--sys/dev/sfxge/common/efx_mac.c481
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.c1607
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.h164
-rw-r--r--sys/dev/sfxge/common/efx_mon.c156
-rw-r--r--sys/dev/sfxge/common/efx_nic.c511
-rw-r--r--sys/dev/sfxge/common/efx_nvram.c556
-rw-r--r--sys/dev/sfxge/common/efx_phy.c199
-rw-r--r--sys/dev/sfxge/common/efx_phy_ids.h53
-rw-r--r--sys/dev/sfxge/common/efx_port.c76
-rw-r--r--sys/dev/sfxge/common/efx_regs.h45
-rw-r--r--sys/dev/sfxge/common/efx_regs_ef10.h1168
-rw-r--r--sys/dev/sfxge/common/efx_regs_mcdi.h9206
-rw-r--r--sys/dev/sfxge/common/efx_regs_pci.h734
-rw-r--r--sys/dev/sfxge/common/efx_rx.c921
-rw-r--r--sys/dev/sfxge/common/efx_sram.c75
-rw-r--r--sys/dev/sfxge/common/efx_tx.c868
-rw-r--r--sys/dev/sfxge/common/efx_types.h122
-rw-r--r--sys/dev/sfxge/common/efx_vpd.c76
-rw-r--r--sys/dev/sfxge/common/efx_wol.c92
-rw-r--r--sys/dev/sfxge/common/hunt_ev.c1010
-rw-r--r--sys/dev/sfxge/common/hunt_filter.c1376
-rw-r--r--sys/dev/sfxge/common/hunt_impl.h1015
-rw-r--r--sys/dev/sfxge/common/hunt_intr.c155
-rw-r--r--sys/dev/sfxge/common/hunt_mac.c685
-rw-r--r--sys/dev/sfxge/common/hunt_mcdi.c465
-rw-r--r--sys/dev/sfxge/common/hunt_nic.c1741
-rw-r--r--sys/dev/sfxge/common/hunt_nvram.c1538
-rw-r--r--sys/dev/sfxge/common/hunt_phy.c701
-rw-r--r--sys/dev/sfxge/common/hunt_rx.c765
-rw-r--r--sys/dev/sfxge/common/hunt_sram.c69
-rwxr-xr-xsys/dev/sfxge/common/hunt_tx.c679
-rw-r--r--sys/dev/sfxge/common/hunt_vpd.c435
-rw-r--r--sys/dev/sfxge/common/mcdi_mon.c552
-rw-r--r--sys/dev/sfxge/common/mcdi_mon.h76
-rw-r--r--sys/dev/sfxge/common/siena_flash.h130
-rw-r--r--sys/dev/sfxge/common/siena_impl.h157
-rw-r--r--sys/dev/sfxge/common/siena_mac.c250
-rw-r--r--sys/dev/sfxge/common/siena_mcdi.c354
-rw-r--r--sys/dev/sfxge/common/siena_mon.c284
-rw-r--r--sys/dev/sfxge/common/siena_nic.c663
-rw-r--r--sys/dev/sfxge/common/siena_nvram.c252
-rw-r--r--sys/dev/sfxge/common/siena_phy.c221
-rw-r--r--sys/dev/sfxge/common/siena_sram.c43
-rw-r--r--sys/dev/sfxge/common/siena_vpd.c81
-rw-r--r--sys/dev/sfxge/sfxge.c339
-rw-r--r--sys/dev/sfxge/sfxge.h82
-rw-r--r--sys/dev/sfxge/sfxge_dma.c45
-rw-r--r--sys/dev/sfxge/sfxge_ev.c113
-rw-r--r--sys/dev/sfxge/sfxge_intr.c58
-rw-r--r--sys/dev/sfxge/sfxge_ioc.h112
-rw-r--r--sys/dev/sfxge/sfxge_mcdi.c179
-rw-r--r--sys/dev/sfxge/sfxge_nvram.c203
-rw-r--r--sys/dev/sfxge/sfxge_port.c202
-rw-r--r--sys/dev/sfxge/sfxge_rx.c183
-rw-r--r--sys/dev/sfxge/sfxge_rx.h56
-rw-r--r--sys/dev/sfxge/sfxge_tx.c501
-rw-r--r--sys/dev/sfxge/sfxge_tx.h51
-rw-r--r--sys/dev/sfxge/sfxge_version.h44
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c8
-rw-r--r--sys/dev/usb/controller/dwc_otg.c108
-rw-r--r--sys/dev/usb/misc/ugold.c405
-rw-r--r--sys/dev/usb/quirk/usb_quirk.c1
-rw-r--r--sys/dev/usb/template/usb_template.c3
-rw-r--r--sys/dev/usb/template/usb_template.h1
-rw-r--r--sys/dev/usb/template/usb_template_midi.c240
-rw-r--r--sys/dev/usb/usb_dev.c3
-rw-r--r--sys/dev/usb/usb_ioctl.h1
-rw-r--r--sys/dev/usb/usbdevs8
-rw-r--r--sys/dev/usb/wlan/if_rsu.c6
-rw-r--r--sys/dev/usb/wlan/if_rum.c16
-rw-r--r--sys/dev/usb/wlan/if_run.c43
-rw-r--r--sys/dev/usb/wlan/if_uath.c18
-rw-r--r--sys/dev/usb/wlan/if_upgt.c8
-rw-r--r--sys/dev/usb/wlan/if_ural.c10
-rw-r--r--sys/dev/usb/wlan/if_urtw.c13
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c6
-rw-r--r--sys/dev/usb/wlan/if_zyd.c10
-rw-r--r--sys/dev/virtio/network/if_vtnet.c2
-rw-r--r--sys/dev/wi/if_wi.c25
-rw-r--r--sys/dev/wi/if_wivar.h2
-rw-r--r--sys/dev/wpi/if_wpi.c24
-rw-r--r--sys/dev/wpi/if_wpivar.h4
-rw-r--r--sys/dev/wtap/if_wtap.c9
-rw-r--r--sys/dev/wtap/if_wtapvar.h1
-rw-r--r--sys/dev/wtap/wtap_hal/hal.c2
-rw-r--r--sys/dev/xen/blkback/blkback.c222
-rw-r--r--sys/dev/xen/blkfront/blkfront.c175
-rw-r--r--sys/dev/xen/blkfront/block.h20
-rw-r--r--sys/fs/devfs/devfs_vnops.c65
-rw-r--r--sys/fs/ext2fs/ext2_vnops.c1
-rw-r--r--sys/fs/fdescfs/fdesc_vfsops.c4
-rw-r--r--sys/fs/nfs/nfs.h4
-rw-r--r--sys/fs/nfs/nfsdport.h2
-rw-r--r--sys/fs/nfs/nfsrvstate.h12
-rw-r--r--sys/fs/nfsserver/nfs_nfsdkrpc.c10
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c13
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c22
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c22
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c80
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsubs.c23
-rw-r--r--sys/fs/procfs/procfs_ctl.c1
-rw-r--r--sys/fs/procfs/procfs_map.c14
-rw-r--r--sys/fs/pseudofs/pseudofs.c2
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c10
-rw-r--r--sys/fs/unionfs/union_vfsops.c9
-rw-r--r--sys/geom/part/g_part_gpt.c2
-rw-r--r--sys/i386/conf/NOTES17
-rw-r--r--sys/i386/i386/elf_machdep.c1
-rw-r--r--sys/i386/i386/exception.s36
-rw-r--r--sys/i386/i386/gdb_machdep.c16
-rw-r--r--sys/i386/i386/initcpu.c1
-rw-r--r--sys/i386/i386/machdep.c9
-rw-r--r--sys/i386/i386/pmap.c1
-rw-r--r--sys/i386/i386/trap.c12
-rw-r--r--sys/i386/ibcs2/ibcs2_misc.c28
-rw-r--r--sys/i386/ibcs2/ibcs2_sysvec.c1
-rw-r--r--sys/i386/include/asmacros.h9
-rw-r--r--sys/i386/include/gdb_machdep.h2
-rw-r--r--sys/i386/include/md_var.h1
-rw-r--r--sys/i386/include/vmparam.h5
-rw-r--r--sys/i386/linux/imgact_linux.c2
-rw-r--r--sys/i386/linux/linux.h135
-rw-r--r--sys/i386/linux/linux_dummy.c20
-rw-r--r--sys/i386/linux/linux_genassym.c3
-rw-r--r--sys/i386/linux/linux_locore.s154
-rw-r--r--sys/i386/linux/linux_machdep.c88
-rw-r--r--sys/i386/linux/linux_proto.h118
-rw-r--r--sys/i386/linux/linux_ptrace.c3
-rw-r--r--sys/i386/linux/linux_syscall.h12
-rw-r--r--sys/i386/linux/linux_syscalls.c11
-rw-r--r--sys/i386/linux/linux_sysent.c47
-rw-r--r--sys/i386/linux/linux_systrace_args.c486
-rw-r--r--sys/i386/linux/linux_sysvec.c200
-rw-r--r--sys/i386/linux/linux_vdso.lds.s65
-rw-r--r--sys/i386/linux/syscalls.master77
-rw-r--r--sys/kern/imgact_aout.c3
-rw-r--r--sys/kern/imgact_elf.c38
-rw-r--r--sys/kern/imgact_gzip.c2
-rw-r--r--sys/kern/init_main.c9
-rw-r--r--sys/kern/kern_descrip.c82
-rw-r--r--sys/kern/kern_event.c41
-rw-r--r--sys/kern/kern_exec.c13
-rw-r--r--sys/kern/kern_exit.c44
-rw-r--r--sys/kern/kern_fork.c10
-rw-r--r--sys/kern/kern_kthread.c2
-rw-r--r--sys/kern/kern_mutex.c34
-rw-r--r--sys/kern/kern_proc.c22
-rw-r--r--sys/kern/kern_prot.c5
-rw-r--r--sys/kern/kern_resource.c92
-rw-r--r--sys/kern/kern_rwlock.c56
-rw-r--r--sys/kern/kern_sig.c13
-rw-r--r--sys/kern/kern_sx.c51
-rw-r--r--sys/kern/kern_synch.c6
-rw-r--r--sys/kern/kern_syscalls.c3
-rw-r--r--sys/kern/kern_tc.c109
-rw-r--r--sys/kern/kern_thr.c49
-rw-r--r--sys/kern/kern_thread.c58
-rw-r--r--sys/kern/p1003_1b.c121
-rw-r--r--sys/kern/subr_prf.c63
-rw-r--r--sys/kern/subr_syscall.c4
-rw-r--r--sys/kern/subr_taskqueue.c19
-rw-r--r--sys/kern/subr_trap.c11
-rw-r--r--sys/kern/subr_uio.c6
-rw-r--r--sys/kern/subr_witness.c17
-rw-r--r--sys/kern/sys_process.c78
-rw-r--r--sys/kern/sysv_shm.c2
-rw-r--r--sys/kern/tty_pts.c4
-rw-r--r--sys/kern/uipc_shm.c60
-rw-r--r--sys/kern/uipc_sockbuf.c4
-rw-r--r--sys/kern/uipc_syscalls.c5
-rw-r--r--sys/kern/uipc_usrreq.c2
-rw-r--r--sys/kern/vfs_cluster.c2
-rw-r--r--sys/kern/vfs_init.c4
-rw-r--r--sys/kern/vfs_mount.c30
-rw-r--r--sys/kern/vfs_subr.c3
-rw-r--r--sys/kern/vfs_vnops.c131
-rw-r--r--sys/libkern/arm/memcpy.S4
-rw-r--r--sys/mips/conf/AR71XX_BASE3
-rw-r--r--sys/mips/conf/AR724X_BASE3
-rw-r--r--sys/mips/conf/AR934X_BASE2
-rw-r--r--sys/mips/include/pcpu.h1
-rw-r--r--sys/mips/include/vmparam.h5
-rw-r--r--sys/mips/mips/elf_machdep.c2
-rw-r--r--sys/mips/mips/freebsd32_machdep.c7
-rw-r--r--sys/mips/mips/pm_machdep.c6
-rw-r--r--sys/modules/Makefile5
-rw-r--r--sys/modules/em/Makefile3
-rw-r--r--sys/modules/geom/geom_map/Makefile8
-rw-r--r--sys/modules/i2c/controllers/Makefile2
-rw-r--r--sys/modules/i2c/controllers/ichiic/Makefile8
-rw-r--r--[-rwxr-xr-x]sys/modules/ixl/Makefile4
-rwxr-xr-xsys/modules/ixlv/Makefile2
-rw-r--r--sys/modules/ixv/Makefile5
-rw-r--r--sys/modules/linprocfs/Makefile7
-rw-r--r--sys/modules/linsysfs/Makefile7
-rw-r--r--sys/modules/linux/Makefile41
-rw-r--r--sys/modules/linux64/Makefile55
-rw-r--r--sys/modules/linux_common/Makefile25
-rw-r--r--sys/modules/proto/Makefile1
-rw-r--r--sys/modules/pseudofs/Makefile6
-rw-r--r--sys/modules/sfxge/Makefile24
-rw-r--r--sys/modules/usb/template/Makefile3
-rw-r--r--sys/modules/usb/ugold/Makefile13
-rw-r--r--sys/net80211/ieee80211.c154
-rw-r--r--sys/net80211/ieee80211.h6
-rw-r--r--sys/net80211/ieee80211_acl.c19
-rw-r--r--sys/net80211/ieee80211_adhoc.c29
-rw-r--r--sys/net80211/ieee80211_amrr.c12
-rw-r--r--sys/net80211/ieee80211_crypto_ccmp.c6
-rw-r--r--sys/net80211/ieee80211_crypto_tkip.c6
-rw-r--r--sys/net80211/ieee80211_crypto_wep.c6
-rw-r--r--sys/net80211/ieee80211_ddb.c1
-rw-r--r--sys/net80211/ieee80211_dfs.c22
-rw-r--r--sys/net80211/ieee80211_freebsd.c126
-rw-r--r--sys/net80211/ieee80211_freebsd.h80
-rw-r--r--sys/net80211/ieee80211_hostap.c21
-rw-r--r--sys/net80211/ieee80211_ht.c17
-rw-r--r--sys/net80211/ieee80211_hwmp.c33
-rw-r--r--sys/net80211/ieee80211_input.c17
-rw-r--r--sys/net80211/ieee80211_input.h1
-rw-r--r--sys/net80211/ieee80211_ioctl.c41
-rw-r--r--sys/net80211/ieee80211_mesh.c75
-rw-r--r--sys/net80211/ieee80211_mesh.h4
-rw-r--r--sys/net80211/ieee80211_monitor.c5
-rw-r--r--sys/net80211/ieee80211_node.c46
-rw-r--r--sys/net80211/ieee80211_output.c28
-rw-r--r--sys/net80211/ieee80211_power.c7
-rw-r--r--sys/net80211/ieee80211_proto.c13
-rw-r--r--sys/net80211/ieee80211_proto.h12
-rw-r--r--sys/net80211/ieee80211_radiotap.c9
-rw-r--r--sys/net80211/ieee80211_ratectl_none.c2
-rw-r--r--sys/net80211/ieee80211_regdomain.c18
-rw-r--r--sys/net80211/ieee80211_rssadapt.c12
-rw-r--r--sys/net80211/ieee80211_scan.c57
-rw-r--r--sys/net80211/ieee80211_scan.h33
-rw-r--r--sys/net80211/ieee80211_scan_sta.c25
-rw-r--r--sys/net80211/ieee80211_scan_sw.c114
-rw-r--r--sys/net80211/ieee80211_scan_sw.h29
-rw-r--r--sys/net80211/ieee80211_sta.c33
-rw-r--r--sys/net80211/ieee80211_superg.c6
-rw-r--r--sys/net80211/ieee80211_tdma.c16
-rw-r--r--sys/net80211/ieee80211_tdma.h3
-rw-r--r--sys/net80211/ieee80211_var.h28
-rw-r--r--sys/net80211/ieee80211_wds.c16
-rw-r--r--sys/netinet/sctp_asconf.c22
-rw-r--r--sys/netinet/sctp_cc_functions.c9
-rw-r--r--sys/netinet/sctp_constants.h27
-rw-r--r--sys/netinet/sctp_indata.c74
-rw-r--r--sys/netinet/sctp_input.c86
-rw-r--r--sys/netinet/sctp_output.c219
-rw-r--r--sys/netinet/sctp_pcb.c7
-rw-r--r--sys/netinet/sctp_sysctl.c1
-rw-r--r--sys/netinet/sctp_timer.c8
-rw-r--r--sys/netinet/sctp_uio.h7
-rw-r--r--sys/netinet/sctp_usrreq.c148
-rw-r--r--sys/netinet/sctputil.c35
-rw-r--r--sys/netinet/tcp_timer.c55
-rw-r--r--sys/netinet/tcp_timer.h6
-rw-r--r--sys/netinet6/in6.c2
-rw-r--r--sys/netinet6/nd6.c3
-rw-r--r--sys/netinet6/sctp6_usrreq.c6
-rw-r--r--sys/netipsec/key.c8
-rw-r--r--sys/netipsec/key.h1
-rw-r--r--sys/netpfil/pf/pf_norm.c12
-rw-r--r--sys/ofed/drivers/infiniband/core/umem.c2
-rw-r--r--sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c3
-rw-r--r--sys/ofed/drivers/net/mlx4/en_netdev.c23
-rw-r--r--sys/ofed/drivers/net/mlx4/port.c157
-rw-r--r--sys/ofed/include/linux/mlx4/device.h23
-rw-r--r--sys/opencrypto/cryptodeflate.c16
-rw-r--r--sys/powerpc/conf/NOTES22
-rw-r--r--sys/powerpc/include/vmparam.h5
-rw-r--r--sys/powerpc/powerpc/elf32_machdep.c1
-rw-r--r--sys/powerpc/powerpc/elf64_machdep.c1
-rw-r--r--sys/powerpc/powerpc/exec_machdep.c6
-rw-r--r--sys/powerpc/powerpc/trap.c4
-rw-r--r--sys/sparc64/include/vmparam.h5
-rw-r--r--sys/sparc64/sparc64/elf_machdep.c1
-rw-r--r--sys/sparc64/sparc64/machdep.c4
-rw-r--r--sys/sparc64/sparc64/trap.c4
-rw-r--r--sys/sys/bus.h2
-rw-r--r--sys/sys/file.h18
-rw-r--r--sys/sys/filedesc.h4
-rw-r--r--sys/sys/ktr_class.h3
-rw-r--r--sys/sys/lockstat.h3
-rw-r--r--sys/sys/mman.h2
-rw-r--r--sys/sys/nlist_aout.h2
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/pmc.h7
-rw-r--r--sys/sys/proc.h17
-rw-r--r--sys/sys/resourcevar.h11
-rw-r--r--sys/sys/sbuf.h10
-rw-r--r--sys/sys/sockio.h2
-rw-r--r--sys/sys/syscallsubr.h17
-rw-r--r--sys/sys/sysent.h1
-rw-r--r--sys/sys/systm.h2
-rw-r--r--sys/sys/user.h21
-rw-r--r--sys/sys/vnode.h3
-rw-r--r--sys/ufs/ffs/ffs_softdep.c181
-rw-r--r--sys/ufs/ffs/ffs_suspend.c2
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c10
-rw-r--r--sys/ufs/ffs/ffs_vnops.c18
-rw-r--r--sys/ufs/ufs/ufs_bmap.c2
-rw-r--r--sys/ufs/ufs/ufs_dirhash.c4
-rw-r--r--sys/vm/swap_pager.c4
-rw-r--r--sys/vm/vm_extern.h14
-rw-r--r--sys/vm/vm_fault.c13
-rw-r--r--sys/vm/vm_glue.c17
-rw-r--r--sys/vm/vm_kern.c3
-rw-r--r--sys/vm/vm_map.c14
-rw-r--r--sys/vm/vm_mmap.c343
-rw-r--r--sys/vm/vm_object.c157
-rw-r--r--sys/vm/vm_object.h1
-rw-r--r--sys/vm/vm_page.c2
-rw-r--r--sys/vm/vm_pageout.c2
-rw-r--r--sys/vm/vm_reserv.c3
-rw-r--r--sys/vm/vm_unix.c8
-rw-r--r--sys/x86/acpica/madt.c97
-rw-r--r--sys/x86/iommu/busdma_dmar.c4
-rw-r--r--sys/x86/iommu/intel_idpgtbl.c8
-rw-r--r--sys/x86/iommu/intel_qi.c2
-rw-r--r--sys/x86/x86/identcpu.c183
-rw-r--r--sys/x86/xen/xenpv.c7
-rw-r--r--sys/xen/blkif.h8
-rw-r--r--sys/xen/interface/io/blkif.h42
720 files changed, 70498 insertions, 14338 deletions
diff --git a/sys/Makefile b/sys/Makefile
index 46d883e1e74d..75757463779c 100644
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -8,9 +8,9 @@ CSCOPEDIRS= boot bsm cam cddl compat conf contrib crypto ddb dev fs gdb \
rpc security sys ufs vm xdr xen ${CSCOPE_ARCHDIR}
.if !defined(CSCOPE_ARCHDIR)
.if defined(ALL_ARCH)
-CSCOPE_ARCHDIR = amd64 arm i386 mips pc98 powerpc sparc64 x86
+CSCOPE_ARCHDIR = amd64 arm arm64 i386 mips pc98 powerpc sparc64 x86
.else
-CSCOPE_ARCHDIR = ${MACHINE}
+CSCOPE_ARCHDIR = ${MACHINE}
.if ${MACHINE} != ${MACHINE_CPUARCH}
CSCOPE_ARCHDIR += ${MACHINE_CPUARCH}
.endif
diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c
index 23fa39b4fd1e..d1cffd9a38cc 100644
--- a/sys/amd64/amd64/elf_machdep.c
+++ b/sys/amd64/amd64/elf_machdep.c
@@ -82,6 +82,7 @@ struct sysentvec elf64_freebsd_sysvec = {
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
diff --git a/sys/amd64/amd64/gdb_machdep.c b/sys/amd64/amd64/gdb_machdep.c
index 5775c8f21578..61ffad629dba 100644
--- a/sys/amd64/amd64/gdb_machdep.c
+++ b/sys/amd64/amd64/gdb_machdep.c
@@ -48,6 +48,8 @@ __FBSDID("$FreeBSD$");
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
+ static uint32_t _kcodesel = GSEL(GCODE_SEL, SEL_KPL);
+ static uint32_t _kdatasel = GSEL(GDATA_SEL, SEL_KPL);
*regsz = gdb_cpu_regsz(regnum);
@@ -76,6 +78,8 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
case 14: return (&kdb_thrctx->pcb_r14);
case 15: return (&kdb_thrctx->pcb_r15);
case 16: return (&kdb_thrctx->pcb_rip);
+ case 18: return (&_kcodesel);
+ case 19: return (&_kdatasel);
}
return (NULL);
}
diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 8551d27906c3..36f2d0f027b2 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -74,6 +74,7 @@ u_int cpu_fxsr; /* SSE enabled */
u_int cpu_mxcsr_mask; /* Valid bits in mxcsr */
u_int cpu_clflush_line_size = 32;
u_int cpu_stdext_feature;
+u_int cpu_stdext_feature2;
u_int cpu_max_ext_state_size;
u_int cpu_mon_mwait_flags; /* MONITOR/MWAIT flags (CPUID.05H.ECX) */
u_int cpu_mon_min_size; /* MONITOR minimum range size, bytes */
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 7cd58b14b262..58cb9786578f 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -398,10 +398,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/* Align to 16 bytes. */
sfp = (struct sigframe *)((unsigned long)sp & ~0xFul);
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
/* Build the argument list for the signal handler. */
regs->tf_rdi = sig; /* arg 1 in %rdi */
regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 118bb340594c..6a3de60af982 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -381,7 +381,7 @@ caddr_t CADDR1 = 0;
static int pmap_flags = PMAP_PDE_SUPERPAGE; /* flags for x86 pmaps */
-int pmap_pcid_enabled = 0;
+int pmap_pcid_enabled = 1;
SYSCTL_INT(_vm_pmap, OID_AUTO, pcid_enabled, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
&pmap_pcid_enabled, 0, "Is TLB Context ID enabled ?");
int invpcid_works = 0;
@@ -3935,7 +3935,6 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
pd_entry_t newpde;
pt_entry_t *firstpte, oldpte, pa, *pte;
pt_entry_t PG_G, PG_A, PG_M, PG_RW, PG_V;
- vm_offset_t oldpteva;
vm_page_t mpte;
int PG_PTE_CACHE;
@@ -3995,10 +3994,9 @@ setpte:
if (!atomic_cmpset_long(pte, oldpte, oldpte & ~PG_RW))
goto setpte;
oldpte &= ~PG_RW;
- oldpteva = (oldpte & PG_FRAME & PDRMASK) |
- (va & ~PDRMASK);
CTR2(KTR_PMAP, "pmap_promote_pde: protect for va %#lx"
- " in pmap %p", oldpteva, pmap);
+ " in pmap %p", (oldpte & PG_FRAME & PDRMASK) |
+ (va & ~PDRMASK), pmap);
}
if ((oldpte & PG_PTE_PROMOTE) != (newpde & PG_PTE_PROMOTE)) {
atomic_add_long(&pmap_pde_p_failures, 1);
@@ -4846,6 +4844,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
PG_PS_FRAME, &lock))) {
*pde = srcptepaddr & ~PG_W;
pmap_resident_count_inc(dst_pmap, NBPDR / PAGE_SIZE);
+ atomic_add_long(&pmap_pde_mappings, 1);
} else
dstmpde->wire_count--;
continue;
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 193d20753e1d..fa74eb286a84 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -257,8 +257,8 @@ trap(struct trapframe *frame)
td->td_pticks = 0;
td->td_frame = frame;
addr = frame->tf_rip;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
switch (type) {
case T_PRIVINFLT: /* privileged instruction fault */
@@ -840,14 +840,8 @@ trap_fatal(frame, eva)
if (frame->tf_rflags & PSL_RF)
printf("resume, ");
printf("IOPL = %ld\n", (frame->tf_rflags & PSL_IOPL) >> 12);
- printf("current process = ");
- if (curproc) {
- printf("%lu (%s)\n",
- (u_long)curproc->p_pid, curthread->td_name ?
- curthread->td_name : "");
- } else {
- printf("Idle\n");
- }
+ printf("current process = %d (%s)\n",
+ curproc->p_pid, curthread->td_name);
#ifdef KDB
if (debugger_on_panic || kdb_active)
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 0d03ed60a425..1fb701611392 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -155,7 +155,6 @@ cpu_fork(td1, p2, td2, flags)
struct pcb *pcb2;
struct mdproc *mdp1, *mdp2;
struct proc_ldt *pldt;
- pmap_t pmap2;
p1 = td1->td_proc;
if ((flags & RFPROC) == 0) {
@@ -218,7 +217,6 @@ cpu_fork(td1, p2, td2, flags)
* Set registers for trampoline to user mode. Leave space for the
* return address on stack. These are the kernel mode register values.
*/
- pmap2 = vmspace_pmap(p2->p_vmspace);
pcb2->pcb_r12 = (register_t)fork_return; /* fork_trampoline argument */
pcb2->pcb_rbp = 0;
pcb2->pcb_rsp = (register_t)td2->td_frame - sizeof(void *);
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index e0fe46577fd7..97eefbfd7c13 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -17,6 +17,23 @@ profile 2
#
options KDTRACE_HOOKS
+# DTrace core
+# NOTE: introduces CDDL-licensed components into the kernel
+#device dtrace
+
+# DTrace modules
+#device dtrace_lockstat
+#device dtrace_profile
+#device dtrace_sdt
+#device dtrace_fbt
+#device dtrace_systrace
+#device dtrace_prototype
+#device dtnfscl
+#device dtmalloc
+
+# Alternatively include all the DTrace modules
+#device dtraceall
+
#####################################################################
# SMP OPTIONS:
diff --git a/sys/amd64/ia32/ia32_reg.c b/sys/amd64/ia32/ia32_reg.c
index 5bc18f12118a..d0e6bfe1318c 100644
--- a/sys/amd64/ia32/ia32_reg.c
+++ b/sys/amd64/ia32/ia32_reg.c
@@ -79,11 +79,9 @@ __FBSDID("$FreeBSD$");
int
fill_regs32(struct thread *td, struct reg32 *regs)
{
- struct pcb *pcb;
struct trapframe *tp;
tp = td->td_frame;
- pcb = td->td_pcb;
if (tp->tf_flags & TF_HASSEGS) {
regs->r_gs = tp->tf_gs;
regs->r_fs = tp->tf_fs;
@@ -113,18 +111,16 @@ fill_regs32(struct thread *td, struct reg32 *regs)
int
set_regs32(struct thread *td, struct reg32 *regs)
{
- struct pcb *pcb;
struct trapframe *tp;
tp = td->td_frame;
if (!EFL_SECURE(regs->r_eflags, tp->tf_rflags) || !CS_SECURE(regs->r_cs))
return (EINVAL);
- pcb = td->td_pcb;
tp->tf_gs = regs->r_gs;
tp->tf_fs = regs->r_fs;
tp->tf_es = regs->r_es;
tp->tf_ds = regs->r_ds;
- set_pcb_flags(pcb, PCB_FULL_IRET);
+ set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
tp->tf_flags = TF_HASSEGS;
tp->tf_rdi = regs->r_edi;
tp->tf_rsi = regs->r_esi;
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index da01647d61df..983101319731 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -360,10 +360,6 @@ ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
} else
fp = (struct ia32_sigframe3 *)regs->tf_rsp - 1;
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
/* Build the argument list for the signal handler. */
sf.sf_signum = sig;
sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
@@ -498,10 +494,6 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1;
PROC_UNLOCK(p);
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
/* Build the argument list for the signal handler. */
sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc;
@@ -643,10 +635,6 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sfp = (struct ia32_sigframe *)((uintptr_t)sp & ~0xF);
PROC_UNLOCK(p);
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
/* Build the argument list for the signal handler. */
sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc;
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index 0813e5fb74d3..954df3ec9c06 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -49,6 +49,7 @@ extern u_int via_feature_rng;
extern u_int via_feature_xcrypt;
extern u_int cpu_clflush_line_size;
extern u_int cpu_stdext_feature;
+extern u_int cpu_stdext_feature2;
extern u_int cpu_fxsr;
extern u_int cpu_high;
extern u_int cpu_id;
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index d3798bcab2e3..1a4e5ab485c8 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -120,13 +120,18 @@ struct vm_object;
struct vm_guest_paging;
struct pmap;
+struct vm_eventinfo {
+ void *rptr; /* rendezvous cookie */
+ int *sptr; /* suspend cookie */
+ int *iptr; /* reqidle cookie */
+};
+
typedef int (*vmm_init_func_t)(int ipinum);
typedef int (*vmm_cleanup_func_t)(void);
typedef void (*vmm_resume_func_t)(void);
typedef void * (*vmi_init_func_t)(struct vm *vm, struct pmap *pmap);
typedef int (*vmi_run_func_t)(void *vmi, int vcpu, register_t rip,
- struct pmap *pmap, void *rendezvous_cookie,
- void *suspend_cookie);
+ struct pmap *pmap, struct vm_eventinfo *info);
typedef void (*vmi_cleanup_func_t)(void *vmi);
typedef int (*vmi_get_register_t)(void *vmi, int vcpu, int num,
uint64_t *retval);
@@ -208,6 +213,7 @@ struct vm_exit *vm_exitinfo(struct vm *vm, int vcpuid);
void vm_exit_suspended(struct vm *vm, int vcpuid, uint64_t rip);
void vm_exit_rendezvous(struct vm *vm, int vcpuid, uint64_t rip);
void vm_exit_astpending(struct vm *vm, int vcpuid, uint64_t rip);
+void vm_exit_reqidle(struct vm *vm, int vcpuid, uint64_t rip);
#ifdef _SYS__CPUSET_H_
/*
@@ -232,17 +238,24 @@ cpuset_t vm_suspended_cpus(struct vm *vm);
#endif /* _SYS__CPUSET_H_ */
static __inline int
-vcpu_rendezvous_pending(void *rendezvous_cookie)
+vcpu_rendezvous_pending(struct vm_eventinfo *info)
+{
+
+ return (*((uintptr_t *)(info->rptr)) != 0);
+}
+
+static __inline int
+vcpu_suspended(struct vm_eventinfo *info)
{
- return (*(uintptr_t *)rendezvous_cookie != 0);
+ return (*info->sptr);
}
static __inline int
-vcpu_suspended(void *suspend_cookie)
+vcpu_reqidle(struct vm_eventinfo *info)
{
- return (*(int *)suspend_cookie);
+ return (*info->iptr);
}
/*
@@ -506,6 +519,7 @@ enum vm_exitcode {
VM_EXITCODE_MONITOR,
VM_EXITCODE_MWAIT,
VM_EXITCODE_SVM,
+ VM_EXITCODE_REQIDLE,
VM_EXITCODE_MAX
};
diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h
index a92dd4eb26c0..07158e88d8cc 100644
--- a/sys/amd64/include/vmparam.h
+++ b/sys/amd64/include/vmparam.h
@@ -90,13 +90,12 @@
#define VM_PHYSSEG_MAX 63
/*
- * Create three free page pools: VM_FREEPOOL_DEFAULT is the default pool
+ * Create two free page pools: VM_FREEPOOL_DEFAULT is the default pool
* from which physical pages are allocated and VM_FREEPOOL_DIRECT is
* the pool from which physical pages for page tables and small UMA
* objects are allocated.
*/
-#define VM_NFREEPOOL 3
-#define VM_FREEPOOL_CACHE 2
+#define VM_NFREEPOOL 2
#define VM_FREEPOOL_DEFAULT 0
#define VM_FREEPOOL_DIRECT 1
diff --git a/sys/amd64/linux/Makefile b/sys/amd64/linux/Makefile
new file mode 100644
index 000000000000..c8899e662a3a
--- /dev/null
+++ b/sys/amd64/linux/Makefile
@@ -0,0 +1,17 @@
+# Makefile for syscall tables
+#
+# $FreeBSD$
+
+all:
+ @echo "make sysent only"
+
+sysent: linux_sysent.c linux_syscall.h linux_proto.h linux_syscalls.c linux_systrace_args.c
+
+linux_sysent.c linux_syscall.h linux_proto.h linux_syscalls.c linux_systrace_args.c: \
+ ../../kern/makesyscalls.sh syscalls.master syscalls.conf
+ -mv -f linux_sysent.c linux_sysent.c.bak
+ -mv -f linux_syscall.h linux_syscall.h.bak
+ -mv -f linux_proto.h linux_proto.h.bak
+ -mv -f linux_syscalls.c linux_syscalls.c.bak
+ -mv -f linux_systrace_args.c linux_systrace_args.c.bak
+ sh ../../kern/makesyscalls.sh syscalls.master syscalls.conf
diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h
new file mode 100644
index 000000000000..c4fe9aede7bd
--- /dev/null
+++ b/sys/amd64/linux/linux.h
@@ -0,0 +1,549 @@
+/*-
+ * Copyright (c) 2013 Dmitry Chagin
+ * Copyright (c) 1994-1996 Søren Schmidt
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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$
+ */
+
+#ifndef _AMD64_LINUX_H_
+#define _AMD64_LINUX_H_
+
+#include <compat/linux/linux.h>
+#include <amd64/linux/linux_syscall.h>
+
+/*
+ * debugging support
+ */
+extern u_char linux_debug_map[];
+#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name)
+#define ARGS(nm, fmt) "linux(%ld/%ld): "#nm"("fmt")\n", \
+ (long)td->td_proc->p_pid, (long)td->td_tid
+#define LMSG(fmt) "linux(%ld/%ld): "fmt"\n", \
+ (long)td->td_proc->p_pid, (long)td->td_tid
+#define LINUX_DTRACE linuxulator
+
+#define PTRIN(v) (void *)(v)
+#define PTROUT(v) (uintptr_t)(v)
+
+#define CP(src,dst,fld) do { (dst).fld = (src).fld; } while (0)
+#define CP2(src,dst,sfld,dfld) do { (dst).dfld = (src).sfld; } while (0)
+#define PTRIN_CP(src,dst,fld) \
+ do { (dst).fld = PTRIN((src).fld); } while (0)
+
+/*
+ * Provide a separate set of types for the Linux types.
+ */
+typedef int32_t l_int;
+typedef int64_t l_long;
+typedef int16_t l_short;
+typedef uint32_t l_uint;
+typedef uint64_t l_ulong;
+typedef uint16_t l_ushort;
+
+typedef l_ulong l_uintptr_t;
+typedef l_long l_clock_t;
+typedef l_int l_daddr_t;
+typedef l_ulong l_dev_t;
+typedef l_uint l_gid_t;
+typedef l_uint l_uid_t;
+typedef l_ulong l_ino_t;
+typedef l_int l_key_t;
+typedef l_long l_loff_t;
+typedef l_uint l_mode_t;
+typedef l_long l_off_t;
+typedef l_int l_pid_t;
+typedef l_ulong l_size_t;
+typedef l_long l_ssize_t;
+typedef l_long l_suseconds_t;
+typedef l_long l_time_t;
+typedef l_int l_timer_t;
+typedef l_int l_mqd_t;
+typedef l_size_t l_socklen_t;
+typedef l_ulong l_fd_mask;
+
+typedef struct {
+ l_int val[2];
+} l_fsid_t;
+
+typedef struct {
+ l_time_t tv_sec;
+ l_suseconds_t tv_usec;
+} l_timeval;
+
+#define l_fd_set fd_set
+
+/*
+ * Miscellaneous
+ */
+#define LINUX_NAME_MAX 255
+#define LINUX_CTL_MAXNAME 10
+
+#define LINUX_AT_COUNT 19 /* Count of used aux entry types. */
+
+struct l___sysctl_args
+{
+ l_uintptr_t name;
+ l_int nlen;
+ l_uintptr_t oldval;
+ l_uintptr_t oldlenp;
+ l_uintptr_t newval;
+ l_size_t newlen;
+ l_ulong __spare[4];
+};
+
+/* Scheduling policies */
+#define LINUX_SCHED_OTHER 0
+#define LINUX_SCHED_FIFO 1
+#define LINUX_SCHED_RR 2
+
+/* Resource limits */
+#define LINUX_RLIMIT_CPU 0
+#define LINUX_RLIMIT_FSIZE 1
+#define LINUX_RLIMIT_DATA 2
+#define LINUX_RLIMIT_STACK 3
+#define LINUX_RLIMIT_CORE 4
+#define LINUX_RLIMIT_RSS 5
+#define LINUX_RLIMIT_NPROC 6
+#define LINUX_RLIMIT_NOFILE 7
+#define LINUX_RLIMIT_MEMLOCK 8
+#define LINUX_RLIMIT_AS 9 /* Address space limit */
+
+#define LINUX_RLIM_NLIMITS 10
+
+struct l_rlimit {
+ l_ulong rlim_cur;
+ l_ulong rlim_max;
+};
+
+/* mmap options */
+#define LINUX_MAP_SHARED 0x0001
+#define LINUX_MAP_PRIVATE 0x0002
+#define LINUX_MAP_FIXED 0x0010
+#define LINUX_MAP_ANON 0x0020
+#define LINUX_MAP_GROWSDOWN 0x0100
+
+/*
+ * stat family of syscalls
+ */
+struct l_timespec {
+ l_time_t tv_sec;
+ l_long tv_nsec;
+};
+
+struct l_newstat {
+ l_dev_t st_dev;
+ l_ino_t st_ino;
+ l_ulong st_nlink;
+ l_uint st_mode;
+ l_uid_t st_uid;
+ l_gid_t st_gid;
+ l_uint __st_pad1;
+ l_dev_t st_rdev;
+ l_off_t st_size;
+ l_long st_blksize;
+ l_long st_blocks;
+ struct l_timespec st_atim;
+ struct l_timespec st_mtim;
+ struct l_timespec st_ctim;
+ l_long __unused1;
+ l_long __unused2;
+ l_long __unused3;
+};
+
+/* sigaction flags */
+#define LINUX_SA_NOCLDSTOP 0x00000001
+#define LINUX_SA_NOCLDWAIT 0x00000002
+#define LINUX_SA_SIGINFO 0x00000004
+#define LINUX_SA_RESTORER 0x04000000
+#define LINUX_SA_ONSTACK 0x08000000
+#define LINUX_SA_RESTART 0x10000000
+#define LINUX_SA_INTERRUPT 0x20000000
+#define LINUX_SA_NOMASK 0x40000000
+#define LINUX_SA_ONESHOT 0x80000000
+
+/* sigprocmask actions */
+#define LINUX_SIG_BLOCK 0
+#define LINUX_SIG_UNBLOCK 1
+#define LINUX_SIG_SETMASK 2
+
+/* sigaltstack */
+#define LINUX_MINSIGSTKSZ 2048
+
+typedef void (*l_handler_t)(l_int);
+
+typedef struct {
+ l_handler_t lsa_handler;
+ l_ulong lsa_flags;
+ l_uintptr_t lsa_restorer;
+ l_sigset_t lsa_mask;
+} l_sigaction_t;
+
+typedef struct {
+ l_uintptr_t ss_sp;
+ l_int ss_flags;
+ l_size_t ss_size;
+} l_stack_t;
+
+struct l_fpstate {
+ u_int16_t cwd;
+ u_int16_t swd;
+ u_int16_t twd;
+ u_int16_t fop;
+ u_int64_t rip;
+ u_int64_t rdp;
+ u_int32_t mxcsr;
+ u_int32_t mxcsr_mask;
+ u_int32_t st_space[32];
+ u_int32_t xmm_space[64];
+ u_int32_t reserved2[24];
+};
+
+struct l_sigcontext {
+ l_ulong sc_r8;
+ l_ulong sc_r9;
+ l_ulong sc_r10;
+ l_ulong sc_r11;
+ l_ulong sc_r12;
+ l_ulong sc_r13;
+ l_ulong sc_r14;
+ l_ulong sc_r15;
+ l_ulong sc_rdi;
+ l_ulong sc_rsi;
+ l_ulong sc_rbp;
+ l_ulong sc_rbx;
+ l_ulong sc_rdx;
+ l_ulong sc_rax;
+ l_ulong sc_rcx;
+ l_ulong sc_rsp;
+ l_ulong sc_rip;
+ l_ulong sc_rflags;
+ l_ushort sc_cs;
+ l_ushort sc_gs;
+ l_ushort sc_fs;
+ l_ushort sc___pad0;
+ l_ulong sc_err;
+ l_ulong sc_trapno;
+ l_sigset_t sc_mask;
+ l_ulong sc_cr2;
+ struct l_fpstate *sc_fpstate;
+ l_ulong sc_reserved1[8];
+};
+
+struct l_ucontext {
+ l_ulong uc_flags;
+ l_uintptr_t uc_link;
+ l_stack_t uc_stack;
+ struct l_sigcontext uc_mcontext;
+ l_sigset_t uc_sigmask;
+};
+
+#define LINUX_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#define LINUX_SI_MAX_SIZE 128
+#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE - \
+ LINUX_SI_PREAMBLE_SIZE) / sizeof(l_int))
+typedef union l_sigval {
+ l_int sival_int;
+ l_uintptr_t sival_ptr;
+} l_sigval_t;
+
+typedef struct l_siginfo {
+ l_int lsi_signo;
+ l_int lsi_errno;
+ l_int lsi_code;
+ union {
+ l_int _pad[LINUX_SI_PAD_SIZE];
+
+ struct {
+ l_pid_t _pid;
+ l_uid_t _uid;
+ } _kill;
+
+ struct {
+ l_timer_t _tid;
+ l_int _overrun;
+ char _pad[sizeof(l_uid_t) - sizeof(int)];
+ union l_sigval _sigval;
+ l_uint _sys_private;
+ } _timer;
+
+ struct {
+ l_pid_t _pid; /* sender's pid */
+ l_uid_t _uid; /* sender's uid */
+ union l_sigval _sigval;
+ } _rt;
+
+ struct {
+ l_pid_t _pid; /* which child */
+ l_uid_t _uid; /* sender's uid */
+ l_int _status; /* exit code */
+ l_clock_t _utime;
+ l_clock_t _stime;
+ } _sigchld;
+
+ struct {
+ l_uintptr_t _addr; /* Faulting insn/memory ref. */
+ } _sigfault;
+
+ struct {
+ l_long _band; /* POLL_IN,POLL_OUT,POLL_MSG */
+ l_int _fd;
+ } _sigpoll;
+ } _sifields;
+} l_siginfo_t;
+
+#define lsi_pid _sifields._kill._pid
+#define lsi_uid _sifields._kill._uid
+#define lsi_tid _sifields._timer._tid
+#define lsi_overrun _sifields._timer._overrun
+#define lsi_sys_private _sifields._timer._sys_private
+#define lsi_status _sifields._sigchld._status
+#define lsi_utime _sifields._sigchld._utime
+#define lsi_stime _sifields._sigchld._stime
+#define lsi_value _sifields._rt._sigval
+#define lsi_int _sifields._rt._sigval.sival_int
+#define lsi_ptr _sifields._rt._sigval.sival_ptr
+#define lsi_addr _sifields._sigfault._addr
+#define lsi_band _sifields._sigpoll._band
+#define lsi_fd _sifields._sigpoll._fd
+
+/*
+ * We make the stack look like Linux expects it when calling a signal
+ * handler, but use the BSD way of calling the handler and sigreturn().
+ * This means that we need to pass the pointer to the handler too.
+ * It is appended to the frame to not interfere with the rest of it.
+ */
+
+struct l_rt_sigframe {
+ struct l_ucontext sf_sc;
+ struct l_siginfo sf_si;
+ l_handler_t sf_handler;
+};
+
+/*
+ * mount flags
+ */
+#define LINUX_MS_RDONLY 0x0001
+#define LINUX_MS_NOSUID 0x0002
+#define LINUX_MS_NODEV 0x0004
+#define LINUX_MS_NOEXEC 0x0008
+#define LINUX_MS_REMOUNT 0x0020
+
+/*
+ * SystemV IPC defines
+ */
+#define LINUX_IPC_RMID 0
+#define LINUX_IPC_SET 1
+#define LINUX_IPC_STAT 2
+#define LINUX_IPC_INFO 3
+
+#define LINUX_SHM_LOCK 11
+#define LINUX_SHM_UNLOCK 12
+#define LINUX_SHM_STAT 13
+#define LINUX_SHM_INFO 14
+
+#define LINUX_SHM_RDONLY 0x1000
+#define LINUX_SHM_RND 0x2000
+#define LINUX_SHM_REMAP 0x4000
+
+/* semctl commands */
+#define LINUX_GETPID 11
+#define LINUX_GETVAL 12
+#define LINUX_GETALL 13
+#define LINUX_GETNCNT 14
+#define LINUX_GETZCNT 15
+#define LINUX_SETVAL 16
+#define LINUX_SETALL 17
+#define LINUX_SEM_STAT 18
+#define LINUX_SEM_INFO 19
+
+union l_semun {
+ l_int val;
+ l_uintptr_t buf;
+ l_uintptr_t array;
+ l_uintptr_t __buf;
+ l_uintptr_t __pad;
+};
+
+struct l_ipc_perm {
+ l_key_t key;
+ l_uid_t uid;
+ l_gid_t gid;
+ l_uid_t cuid;
+ l_gid_t cgid;
+ l_ushort mode;
+ l_ushort seq;
+};
+
+/*
+ * Socket defines
+ */
+
+#define LINUX_SOL_SOCKET 1
+#define LINUX_SOL_IP 0
+#define LINUX_SOL_IPX 256
+#define LINUX_SOL_AX25 257
+#define LINUX_SOL_TCP 6
+#define LINUX_SOL_UDP 17
+
+#define LINUX_SO_DEBUG 1
+#define LINUX_SO_REUSEADDR 2
+#define LINUX_SO_TYPE 3
+#define LINUX_SO_ERROR 4
+#define LINUX_SO_DONTROUTE 5
+#define LINUX_SO_BROADCAST 6
+#define LINUX_SO_SNDBUF 7
+#define LINUX_SO_RCVBUF 8
+#define LINUX_SO_KEEPALIVE 9
+#define LINUX_SO_OOBINLINE 10
+#define LINUX_SO_NO_CHECK 11
+#define LINUX_SO_PRIORITY 12
+#define LINUX_SO_LINGER 13
+#define LINUX_SO_PASSCRED 16
+#define LINUX_SO_PEERCRED 17
+#define LINUX_SO_RCVLOWAT 18
+#define LINUX_SO_SNDLOWAT 19
+#define LINUX_SO_RCVTIMEO 20
+#define LINUX_SO_SNDTIMEO 21
+#define LINUX_SO_TIMESTAMP 29
+#define LINUX_SO_ACCEPTCONN 30
+
+#define LINUX_IP_TOS 1
+#define LINUX_IP_TTL 2
+#define LINUX_IP_HDRINCL 3
+#define LINUX_IP_OPTIONS 4
+
+#define LINUX_IP_MULTICAST_IF 32
+#define LINUX_IP_MULTICAST_TTL 33
+#define LINUX_IP_MULTICAST_LOOP 34
+#define LINUX_IP_ADD_MEMBERSHIP 35
+#define LINUX_IP_DROP_MEMBERSHIP 36
+
+struct l_sockaddr {
+ l_ushort sa_family;
+ char sa_data[14];
+};
+
+struct l_ifmap {
+ l_ulong mem_start;
+ l_ulong mem_end;
+ l_ushort base_addr;
+ u_char irq;
+ u_char dma;
+ u_char port;
+} __packed;
+
+#define LINUX_IFHWADDRLEN 6
+#define LINUX_IFNAMSIZ 16
+
+struct l_ifreq {
+ union {
+ char ifrn_name[LINUX_IFNAMSIZ];
+ } ifr_ifrn;
+
+ union {
+ struct l_sockaddr ifru_addr;
+ struct l_sockaddr ifru_dstaddr;
+ struct l_sockaddr ifru_broadaddr;
+ struct l_sockaddr ifru_netmask;
+ struct l_sockaddr ifru_hwaddr;
+ l_short ifru_flags[1];
+ l_int ifru_metric;
+ l_int ifru_mtu;
+ struct l_ifmap ifru_map;
+ char ifru_slave[LINUX_IFNAMSIZ];
+ l_uintptr_t ifru_data;
+ } ifr_ifru;
+} __packed;
+
+#define ifr_name ifr_ifrn.ifrn_name /* Interface name */
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+
+struct l_ifconf {
+ int ifc_len;
+ union {
+ l_uintptr_t ifcu_buf;
+ l_uintptr_t ifcu_req;
+ } ifc_ifcu;
+};
+
+#define ifc_buf ifc_ifcu.ifcu_buf
+#define ifc_req ifc_ifcu.ifcu_req
+
+/*
+ * poll()
+ */
+#define LINUX_POLLIN 0x0001
+#define LINUX_POLLPRI 0x0002
+#define LINUX_POLLOUT 0x0004
+#define LINUX_POLLERR 0x0008
+#define LINUX_POLLHUP 0x0010
+#define LINUX_POLLNVAL 0x0020
+#define LINUX_POLLRDNORM 0x0040
+#define LINUX_POLLRDBAND 0x0080
+#define LINUX_POLLWRNORM 0x0100
+#define LINUX_POLLWRBAND 0x0200
+#define LINUX_POLLMSG 0x0400
+
+struct l_pollfd {
+ l_int fd;
+ l_short events;
+ l_short revents;
+};
+
+
+#define LINUX_CLONE_VM 0x00000100
+#define LINUX_CLONE_FS 0x00000200
+#define LINUX_CLONE_FILES 0x00000400
+#define LINUX_CLONE_SIGHAND 0x00000800
+#define LINUX_CLONE_PID 0x00001000 /* No longer exist in Linux */
+#define LINUX_CLONE_VFORK 0x00004000
+#define LINUX_CLONE_PARENT 0x00008000
+#define LINUX_CLONE_THREAD 0x00010000
+#define LINUX_CLONE_SETTLS 0x00080000
+#define LINUX_CLONE_PARENT_SETTID 0x00100000
+#define LINUX_CLONE_CHILD_CLEARTID 0x00200000
+#define LINUX_CLONE_CHILD_SETTID 0x01000000
+
+#define LINUX_ARCH_SET_GS 0x1001
+#define LINUX_ARCH_SET_FS 0x1002
+#define LINUX_ARCH_GET_GS 0x1003
+#define LINUX_ARCH_GET_FS 0x1004
+
+#define linux_copyout_rusage(r, u) copyout(r, u, sizeof(*r))
+
+/* robust futexes */
+struct linux_robust_list {
+ l_uintptr_t next;
+};
+
+struct linux_robust_list_head {
+ struct linux_robust_list list;
+ l_long futex_offset;
+ l_uintptr_t pending_list;
+};
+
+#endif /* !_AMD64_LINUX_H_ */
diff --git a/sys/amd64/linux/linux_dummy.c b/sys/amd64/linux/linux_dummy.c
new file mode 100644
index 000000000000..96cf8d907f9d
--- /dev/null
+++ b/sys/amd64/linux/linux_dummy.c
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 2013 Dmitry Chagin
+ * 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
+ * in this position and unchanged.
+ * 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 ``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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+#include "opt_kdtrace.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/sdt.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <amd64/linux/linux.h>
+#include <amd64/linux/linux_proto.h>
+#include <compat/linux/linux_dtrace.h>
+#include <compat/linux/linux_util.h>
+
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+DUMMY(mincore);
+DUMMY(sendfile);
+DUMMY(ptrace);
+DUMMY(syslog);
+DUMMY(setfsuid);
+DUMMY(setfsgid);
+DUMMY(sysfs);
+DUMMY(vhangup);
+DUMMY(pivot_root);
+DUMMY(adjtimex);
+DUMMY(swapoff);
+DUMMY(create_module);
+DUMMY(init_module);
+DUMMY(delete_module);
+DUMMY(get_kernel_syms);
+DUMMY(query_module);
+DUMMY(quotactl);
+DUMMY(nfsservctl);
+DUMMY(getpmsg);
+DUMMY(putpmsg);
+DUMMY(afs_syscall);
+DUMMY(tuxcall);
+DUMMY(security);
+DUMMY(set_thread_area);
+DUMMY(lookup_dcookie);
+DUMMY(epoll_ctl_old);
+DUMMY(epoll_wait_old);
+DUMMY(remap_file_pages);
+DUMMY(semtimedop);
+DUMMY(mbind);
+DUMMY(get_mempolicy);
+DUMMY(set_mempolicy);
+DUMMY(mq_open);
+DUMMY(mq_unlink);
+DUMMY(mq_timedsend);
+DUMMY(mq_timedreceive);
+DUMMY(mq_notify);
+DUMMY(mq_getsetattr);
+DUMMY(kexec_load);
+DUMMY(add_key);
+DUMMY(request_key);
+DUMMY(keyctl);
+DUMMY(ioprio_set);
+DUMMY(ioprio_get);
+DUMMY(inotify_init);
+DUMMY(inotify_add_watch);
+DUMMY(inotify_rm_watch);
+DUMMY(migrate_pages);
+DUMMY(unshare);
+DUMMY(splice);
+DUMMY(tee);
+DUMMY(sync_file_range);
+DUMMY(vmsplice);
+DUMMY(move_pages);
+DUMMY(signalfd);
+DUMMY(timerfd);
+DUMMY(timerfd_settime);
+DUMMY(timerfd_gettime);
+DUMMY(signalfd4);
+DUMMY(inotify_init1);
+DUMMY(preadv);
+DUMMY(pwritev);
+DUMMY(rt_tsigqueueinfo);
+DUMMY(perf_event_open);
+DUMMY(fanotify_init);
+DUMMY(fanotify_mark);
+DUMMY(name_to_handle_at);
+DUMMY(open_by_handle_at);
+DUMMY(clock_adjtime);
+DUMMY(setns);
+DUMMY(process_vm_readv);
+DUMMY(process_vm_writev);
+DUMMY(kcmp);
+DUMMY(finit_module);
+
+#define DUMMY_XATTR(s) \
+int \
+linux_ ## s ## xattr( \
+ struct thread *td, struct linux_ ## s ## xattr_args *arg) \
+{ \
+ \
+ return (ENOATTR); \
+}
+DUMMY_XATTR(set);
+DUMMY_XATTR(lset);
+DUMMY_XATTR(fset);
+DUMMY_XATTR(get);
+DUMMY_XATTR(lget);
+DUMMY_XATTR(fget);
+DUMMY_XATTR(list);
+DUMMY_XATTR(llist);
+DUMMY_XATTR(flist);
+DUMMY_XATTR(remove);
+DUMMY_XATTR(lremove);
+DUMMY_XATTR(fremove);
diff --git a/sys/amd64/linux/linux_genassym.c b/sys/amd64/linux/linux_genassym.c
new file mode 100644
index 000000000000..0edb6a043531
--- /dev/null
+++ b/sys/amd64/linux/linux_genassym.c
@@ -0,0 +1,15 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/assym.h>
+#include <sys/systm.h>
+
+#include <amd64/linux/linux.h>
+#include <compat/linux/linux_mib.h>
+
+ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler));
+ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc));
+ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext));
+ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE);
+ASSYM(LINUX_SC_RSP, offsetof(struct l_sigcontext, sc_rsp));
diff --git a/sys/amd64/linux/linux_ipc64.h b/sys/amd64/linux/linux_ipc64.h
new file mode 100644
index 000000000000..913fc1a51723
--- /dev/null
+++ b/sys/amd64/linux/linux_ipc64.h
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 2002 Maxim Sobolev <sobomax@FreeBSD.org>
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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$
+ */
+
+#ifndef _AMD64_LINUX_LINUX_IPC64_H_
+#define _AMD64_LINUX_LINUX_IPC64_H_
+
+/*
+ * The ipc64_perm structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_ipc64_perm
+{
+ l_key_t key;
+ l_uid_t uid;
+ l_gid_t gid;
+ l_uid_t cuid;
+ l_gid_t cgid;
+ l_mode_t mode;
+ l_ushort __pad1;
+ l_ushort seq;
+ l_ushort __pad2;
+ l_ulong __unused1;
+ l_ulong __unused2;
+};
+
+/*
+ * The msqid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_msqid64_ds {
+ struct l_ipc64_perm msg_perm;
+ l_time_t msg_stime; /* last msgsnd time */
+ l_ulong __unused1;
+ l_time_t msg_rtime; /* last msgrcv time */
+ l_ulong __unused2;
+ l_time_t msg_ctime; /* last change time */
+ l_ulong __unused3;
+ l_ulong msg_cbytes; /* current number of bytes on queue */
+ l_ulong msg_qnum; /* number of messages in queue */
+ l_ulong msg_qbytes; /* max number of bytes on queue */
+ l_pid_t msg_lspid; /* pid of last msgsnd */
+ l_pid_t msg_lrpid; /* last receive pid */
+ l_ulong __unused4;
+ l_ulong __unused5;
+};
+
+/*
+ * The semid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_semid64_ds {
+ struct l_ipc64_perm sem_perm; /* permissions */
+ l_time_t sem_otime; /* last semop time */
+ l_ulong __unused1;
+ l_time_t sem_ctime; /* last change time */
+ l_ulong __unused2;
+ l_ulong sem_nsems; /* no. of semaphores in array */
+ l_ulong __unused3;
+ l_ulong __unused4;
+};
+
+/*
+ * The shmid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_shmid64_ds {
+ struct l_ipc64_perm shm_perm; /* operation perms */
+ l_size_t shm_segsz; /* size of segment (bytes) */
+ l_time_t shm_atime; /* last attach time */
+ l_time_t shm_dtime; /* last detach time */
+ l_time_t shm_ctime; /* last change time */
+ l_pid_t shm_cpid; /* pid of creator */
+ l_pid_t shm_lpid; /* pid of last operator */
+ l_ulong shm_nattch; /* no. of current attaches */
+ l_ulong __unused4;
+ l_ulong __unused5;
+};
+
+struct l_shminfo64 {
+ l_ulong shmmax;
+ l_ulong shmmin;
+ l_ulong shmmni;
+ l_ulong shmseg;
+ l_ulong shmall;
+ l_ulong __unused1;
+ l_ulong __unused2;
+ l_ulong __unused3;
+ l_ulong __unused4;
+};
+
+#endif /* !_AMD64_LINUX_LINUX_IPC64_H_ */
diff --git a/sys/amd64/linux/linux_locore.s b/sys/amd64/linux/linux_locore.s
new file mode 100644
index 000000000000..5dcc09aa2c9d
--- /dev/null
+++ b/sys/amd64/linux/linux_locore.s
@@ -0,0 +1,76 @@
+/* $FreeBSD$ */
+
+#include "linux_assym.h" /* system definitions */
+#include <machine/asmacros.h> /* miscellaneous asm macros */
+
+#include <amd64/linux/linux_syscall.h> /* system call numbers */
+
+ .data
+
+ .globl linux_platform
+linux_platform:
+ .asciz "x86_64"
+
+
+ .text
+/*
+ * To avoid excess stack frame the signal trampoline code emulates
+ * the 'call' instruction.
+ */
+NON_GPROF_ENTRY(linux_rt_sigcode)
+ movq %rsp, %rbx /* preserve sigframe */
+ call .getip
+.getip:
+ popq %rax
+ add $.startrtsigcode-.getip, %rax /* ret address */
+ pushq %rax
+ jmp *LINUX_RT_SIGF_HANDLER(%rbx)
+.startrtsigcode:
+ movq $LINUX_SYS_linux_rt_sigreturn,%rax /* linux_rt_sigreturn() */
+ syscall /* enter kernel with args */
+ hlt
+0: jmp 0b
+
+NON_GPROF_ENTRY(__vdso_clock_gettime)
+ movq $LINUX_SYS_linux_clock_gettime,%rax
+ syscall
+ ret
+.weak clock_gettime
+.set clock_gettime, __vdso_clock_gettime
+
+NON_GPROF_ENTRY(__vdso_time)
+ movq $LINUX_SYS_linux_time,%rax
+ syscall
+ ret
+.weak time
+.set time, __vdso_time
+
+NON_GPROF_ENTRY(__vdso_gettimeofday)
+ movq $LINUX_SYS_gettimeofday,%rax
+ syscall
+ ret
+.weak gettimeofday
+.set gettimeofday, __vdso_gettimeofday
+
+NON_GPROF_ENTRY(__vdso_getcpu)
+ movq $-38,%rax /* not implemented */
+ ret
+.weak getcpu
+.set getcpu, __vdso_getcpu
+
+#if 0
+ .section .note.Linux, "a",@note
+ .long 2f - 1f /* namesz */
+ .balign 4
+ .long 4f - 3f /* descsz */
+ .long 0
+1:
+ .asciz "Linux"
+2:
+ .balign 4
+3:
+ .long LINUX_VERSION_CODE
+4:
+ .balign 4
+ .previous
+#endif
diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c
new file mode 100644
index 000000000000..451e4b4bf25b
--- /dev/null
+++ b/sys/amd64/linux/linux_machdep.c
@@ -0,0 +1,433 @@
+/*-
+ * Copyright (c) 2013 Dmitry Chagin
+ * Copyright (c) 2004 Tim J. Robbins
+ * Copyright (c) 2002 Doug Rabson
+ * Copyright (c) 2000 Marcel Moolenaar
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/capability.h>
+#include <sys/dirent.h>
+#include <sys/file.h>
+#include <sys/fcntl.h>
+#include <sys/filedesc.h>
+#include <sys/clock.h>
+#include <sys/imgact.h>
+#include <sys/ktr.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/mutex.h>
+#include <sys/priv.h>
+#include <sys/proc.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
+#include <sys/sched.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysproto.h>
+#include <sys/vnode.h>
+#include <sys/unistd.h>
+#include <sys/wait.h>
+
+#include <security/mac/mac_framework.h>
+
+#include <ufs/ufs/extattr.h>
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/ufsmount.h>
+
+#include <machine/frame.h>
+#include <machine/md_var.h>
+#include <machine/pcb.h>
+#include <machine/psl.h>
+#include <machine/segments.h>
+#include <machine/specialreg.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+
+#include <amd64/linux/linux.h>
+#include <amd64/linux/linux_proto.h>
+#include <compat/linux/linux_ipc.h>
+#include <compat/linux/linux_file.h>
+#include <compat/linux/linux_misc.h>
+#include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_util.h>
+#include <compat/linux/linux_emul.h>
+
+
+int
+linux_execve(struct thread *td, struct linux_execve_args *args)
+{
+ struct image_args eargs;
+ char *path;
+ int error;
+
+ LCONVPATHEXIST(td, args->path, &path);
+
+ LINUX_CTR(execve);
+
+ error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, args->argp,
+ args->envp);
+ free(path, M_TEMP);
+ if (error == 0)
+ error = linux_common_execve(td, &eargs);
+ return (error);
+}
+
+int
+linux_set_upcall_kse(struct thread *td, register_t stack)
+{
+
+ if (stack)
+ td->td_frame->tf_rsp = stack;
+
+ /*
+ * The newly created Linux thread returns
+ * to the user space by the same path that a parent do.
+ */
+ td->td_frame->tf_rax = 0;
+ return (0);
+}
+
+#define STACK_SIZE (2 * 1024 * 1024)
+#define GUARD_SIZE (4 * PAGE_SIZE)
+
+int
+linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
+{
+ struct proc *p = td->td_proc;
+ struct mmap_args /* {
+ caddr_t addr;
+ size_t len;
+ int prot;
+ int flags;
+ int fd;
+ long pad;
+ off_t pos;
+ } */ bsd_args;
+ int error;
+ struct file *fp;
+ cap_rights_t rights;
+
+ LINUX_CTR6(mmap2, "0x%lx, %ld, %ld, 0x%08lx, %ld, 0x%lx",
+ args->addr, args->len, args->prot,
+ args->flags, args->fd, args->pgoff);
+
+ error = 0;
+ bsd_args.flags = 0;
+ fp = NULL;
+
+ /*
+ * Linux mmap(2):
+ * You must specify exactly one of MAP_SHARED and MAP_PRIVATE
+ */
+ if (! ((args->flags & LINUX_MAP_SHARED) ^
+ (args->flags & LINUX_MAP_PRIVATE)))
+ return (EINVAL);
+
+ if (args->flags & LINUX_MAP_SHARED)
+ bsd_args.flags |= MAP_SHARED;
+ if (args->flags & LINUX_MAP_PRIVATE)
+ bsd_args.flags |= MAP_PRIVATE;
+ if (args->flags & LINUX_MAP_FIXED)
+ bsd_args.flags |= MAP_FIXED;
+ if (args->flags & LINUX_MAP_ANON)
+ bsd_args.flags |= MAP_ANON;
+ else
+ bsd_args.flags |= MAP_NOSYNC;
+ if (args->flags & LINUX_MAP_GROWSDOWN)
+ bsd_args.flags |= MAP_STACK;
+
+ /*
+ * PROT_READ, PROT_WRITE, or PROT_EXEC implies PROT_READ and PROT_EXEC
+ * on Linux/i386. We do this to ensure maximum compatibility.
+ * Linux/ia64 does the same in i386 emulation mode.
+ */
+ bsd_args.prot = args->prot;
+ if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
+ bsd_args.prot |= PROT_READ | PROT_EXEC;
+
+ /* Linux does not check file descriptor when MAP_ANONYMOUS is set. */
+ bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : args->fd;
+ if (bsd_args.fd != -1) {
+ /*
+ * Linux follows Solaris mmap(2) description:
+ * The file descriptor fildes is opened with
+ * read permission, regardless of the
+ * protection options specified.
+ */
+
+ error = fget(td, bsd_args.fd,
+ cap_rights_init(&rights, CAP_MMAP), &fp);
+ if (error != 0 )
+ return (error);
+ if (fp->f_type != DTYPE_VNODE) {
+ fdrop(fp, td);
+ return (EINVAL);
+ }
+
+ /* Linux mmap() just fails for O_WRONLY files */
+ if (!(fp->f_flag & FREAD)) {
+ fdrop(fp, td);
+ return (EACCES);
+ }
+
+ fdrop(fp, td);
+ }
+
+ if (args->flags & LINUX_MAP_GROWSDOWN) {
+ /*
+ * The Linux MAP_GROWSDOWN option does not limit auto
+ * growth of the region. Linux mmap with this option
+ * takes as addr the inital BOS, and as len, the initial
+ * region size. It can then grow down from addr without
+ * limit. However, Linux threads has an implicit internal
+ * limit to stack size of STACK_SIZE. Its just not
+ * enforced explicitly in Linux. But, here we impose
+ * a limit of (STACK_SIZE - GUARD_SIZE) on the stack
+ * region, since we can do this with our mmap.
+ *
+ * Our mmap with MAP_STACK takes addr as the maximum
+ * downsize limit on BOS, and as len the max size of
+ * the region. It then maps the top SGROWSIZ bytes,
+ * and auto grows the region down, up to the limit
+ * in addr.
+ *
+ * If we don't use the MAP_STACK option, the effect
+ * of this code is to allocate a stack region of a
+ * fixed size of (STACK_SIZE - GUARD_SIZE).
+ */
+
+ if ((caddr_t)PTRIN(args->addr) + args->len >
+ p->p_vmspace->vm_maxsaddr) {
+ /*
+ * Some Linux apps will attempt to mmap
+ * thread stacks near the top of their
+ * address space. If their TOS is greater
+ * than vm_maxsaddr, vm_map_growstack()
+ * will confuse the thread stack with the
+ * process stack and deliver a SEGV if they
+ * attempt to grow the thread stack past their
+ * current stacksize rlimit. To avoid this,
+ * adjust vm_maxsaddr upwards to reflect
+ * the current stacksize rlimit rather
+ * than the maximum possible stacksize.
+ * It would be better to adjust the
+ * mmap'ed region, but some apps do not check
+ * mmap's return value.
+ */
+ PROC_LOCK(p);
+ p->p_vmspace->vm_maxsaddr = (char *)USRSTACK -
+ lim_cur_proc(p, RLIMIT_STACK);
+ PROC_UNLOCK(p);
+ }
+
+ /*
+ * This gives us our maximum stack size and a new BOS.
+ * If we're using VM_STACK, then mmap will just map
+ * the top SGROWSIZ bytes, and let the stack grow down
+ * to the limit at BOS. If we're not using VM_STACK
+ * we map the full stack, since we don't have a way
+ * to autogrow it.
+ */
+ if (args->len > STACK_SIZE - GUARD_SIZE) {
+ bsd_args.addr = (caddr_t)PTRIN(args->addr);
+ bsd_args.len = args->len;
+ } else {
+ bsd_args.addr = (caddr_t)PTRIN(args->addr) -
+ (STACK_SIZE - GUARD_SIZE - args->len);
+ bsd_args.len = STACK_SIZE - GUARD_SIZE;
+ }
+ } else {
+ bsd_args.addr = (caddr_t)PTRIN(args->addr);
+ bsd_args.len = args->len;
+ }
+ bsd_args.pos = (off_t)args->pgoff;
+
+ error = sys_mmap(td, &bsd_args);
+
+ LINUX_CTR2(mmap2, "return: %d (%p)",
+ error, td->td_retval[0]);
+ return (error);
+}
+
+int
+linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
+{
+ struct mprotect_args bsd_args;
+
+ LINUX_CTR(mprotect);
+
+ bsd_args.addr = uap->addr;
+ bsd_args.len = uap->len;
+ bsd_args.prot = uap->prot;
+ if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
+ bsd_args.prot |= PROT_READ | PROT_EXEC;
+ return (sys_mprotect(td, &bsd_args));
+}
+
+int
+linux_iopl(struct thread *td, struct linux_iopl_args *args)
+{
+ int error;
+
+ LINUX_CTR(iopl);
+
+ if (args->level > 3)
+ return (EINVAL);
+ if ((error = priv_check(td, PRIV_IO)) != 0)
+ return (error);
+ if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
+ return (error);
+ td->td_frame->tf_rflags = (td->td_frame->tf_rflags & ~PSL_IOPL) |
+ (args->level * (PSL_IOPL / 3));
+
+ return (0);
+}
+
+int
+linux_rt_sigsuspend(struct thread *td, struct linux_rt_sigsuspend_args *uap)
+{
+ l_sigset_t lmask;
+ sigset_t sigmask;
+ int error;
+
+ LINUX_CTR2(rt_sigsuspend, "%p, %ld",
+ uap->newset, uap->sigsetsize);
+
+ if (uap->sigsetsize != sizeof(l_sigset_t))
+ return (EINVAL);
+
+ error = copyin(uap->newset, &lmask, sizeof(l_sigset_t));
+ if (error)
+ return (error);
+
+ linux_to_bsd_sigset(&lmask, &sigmask);
+ return (kern_sigsuspend(td, sigmask));
+}
+
+int
+linux_pause(struct thread *td, struct linux_pause_args *args)
+{
+ struct proc *p = td->td_proc;
+ sigset_t sigmask;
+
+ LINUX_CTR(pause);
+
+ PROC_LOCK(p);
+ sigmask = td->td_sigmask;
+ PROC_UNLOCK(p);
+ return (kern_sigsuspend(td, sigmask));
+}
+
+int
+linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap)
+{
+ stack_t ss, oss;
+ l_stack_t lss;
+ int error;
+
+ LINUX_CTR2(sigaltstack, "%p, %p", uap->uss, uap->uoss);
+
+ if (uap->uss != NULL) {
+ error = copyin(uap->uss, &lss, sizeof(l_stack_t));
+ if (error)
+ return (error);
+
+ ss.ss_sp = PTRIN(lss.ss_sp);
+ ss.ss_size = lss.ss_size;
+ ss.ss_flags = linux_to_bsd_sigaltstack(lss.ss_flags);
+ }
+ error = kern_sigaltstack(td, (uap->uss != NULL) ? &ss : NULL,
+ (uap->uoss != NULL) ? &oss : NULL);
+ if (!error && uap->uoss != NULL) {
+ lss.ss_sp = PTROUT(oss.ss_sp);
+ lss.ss_size = oss.ss_size;
+ lss.ss_flags = bsd_to_linux_sigaltstack(oss.ss_flags);
+ error = copyout(&lss, uap->uoss, sizeof(l_stack_t));
+ }
+
+ return (error);
+}
+
+/* XXX do all */
+int
+linux_arch_prctl(struct thread *td, struct linux_arch_prctl_args *args)
+{
+ int error;
+ struct pcb *pcb;
+
+ LINUX_CTR2(arch_prctl, "0x%x, %p", args->code, args->addr);
+
+ error = ENOTSUP;
+ pcb = td->td_pcb;
+
+ switch (args->code) {
+ case LINUX_ARCH_GET_GS:
+ error = copyout(&pcb->pcb_gsbase, (unsigned long *)args->addr,
+ sizeof(args->addr));
+ break;
+ case LINUX_ARCH_SET_GS:
+ if (args->addr >= VM_MAXUSER_ADDRESS)
+ return(EPERM);
+ break;
+ case LINUX_ARCH_GET_FS:
+ error = copyout(&pcb->pcb_fsbase, (unsigned long *)args->addr,
+ sizeof(args->addr));
+ break;
+ case LINUX_ARCH_SET_FS:
+ error = linux_set_cloned_tls(td, (void *)args->addr);
+ break;
+ default:
+ error = EINVAL;
+ }
+ return (error);
+}
+
+int
+linux_set_cloned_tls(struct thread *td, void *desc)
+{
+ struct pcb *pcb;
+
+ if ((uint64_t)desc >= VM_MAXUSER_ADDRESS)
+ return (EPERM);
+
+ pcb = td->td_pcb;
+ pcb->pcb_fsbase = (register_t)desc;
+ td->td_frame->tf_fs = _ufssel;
+
+ return (0);
+}
diff --git a/sys/amd64/linux/linux_proto.h b/sys/amd64/linux/linux_proto.h
new file mode 100644
index 000000000000..795a830cba5b
--- /dev/null
+++ b/sys/amd64/linux/linux_proto.h
@@ -0,0 +1,1663 @@
+/*
+ * System call prototypes.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * $FreeBSD$
+ * created from FreeBSD: head/sys/amd64/linux/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
+ */
+
+#ifndef _LINUX_SYSPROTO_H_
+#define _LINUX_SYSPROTO_H_
+
+#include <sys/signal.h>
+#include <sys/acl.h>
+#include <sys/cpuset.h>
+#include <sys/_ffcounter.h>
+#include <sys/_semaphore.h>
+#include <sys/ucontext.h>
+#include <sys/wait.h>
+
+#include <bsm/audit_kevents.h>
+
+struct proc;
+
+struct thread;
+
+#define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \
+ 0 : sizeof(register_t) - sizeof(t))
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define PADL_(t) 0
+#define PADR_(t) PAD_(t)
+#else
+#define PADL_(t) PAD_(t)
+#define PADR_(t) 0
+#endif
+
+#define nosys linux_nosys
+struct linux_open_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+};
+struct linux_newstat_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)];
+};
+struct linux_newfstat_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)];
+};
+struct linux_newlstat_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)];
+};
+struct linux_lseek_args {
+ char fdes_l_[PADL_(l_uint)]; l_uint fdes; char fdes_r_[PADR_(l_uint)];
+ char off_l_[PADL_(l_off_t)]; l_off_t off; char off_r_[PADR_(l_off_t)];
+ char whence_l_[PADL_(l_int)]; l_int whence; char whence_r_[PADR_(l_int)];
+};
+struct linux_mmap2_args {
+ char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)];
+ char len_l_[PADL_(l_ulong)]; l_ulong len; char len_r_[PADR_(l_ulong)];
+ char prot_l_[PADL_(l_ulong)]; l_ulong prot; char prot_r_[PADR_(l_ulong)];
+ char flags_l_[PADL_(l_ulong)]; l_ulong flags; char flags_r_[PADR_(l_ulong)];
+ char fd_l_[PADL_(l_ulong)]; l_ulong fd; char fd_r_[PADR_(l_ulong)];
+ char pgoff_l_[PADL_(l_ulong)]; l_ulong pgoff; char pgoff_r_[PADR_(l_ulong)];
+};
+struct linux_mprotect_args {
+ char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
+ char len_l_[PADL_(int)]; int len; char len_r_[PADR_(int)];
+ char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
+};
+struct linux_brk_args {
+ char dsend_l_[PADL_(l_ulong)]; l_ulong dsend; char dsend_r_[PADR_(l_ulong)];
+};
+struct linux_rt_sigaction_args {
+ char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
+ char act_l_[PADL_(l_sigaction_t *)]; l_sigaction_t * act; char act_r_[PADR_(l_sigaction_t *)];
+ char oact_l_[PADL_(l_sigaction_t *)]; l_sigaction_t * oact; char oact_r_[PADR_(l_sigaction_t *)];
+ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
+};
+struct linux_rt_sigprocmask_args {
+ char how_l_[PADL_(l_int)]; l_int how; char how_r_[PADR_(l_int)];
+ char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
+ char omask_l_[PADL_(l_sigset_t *)]; l_sigset_t * omask; char omask_r_[PADR_(l_sigset_t *)];
+ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
+};
+struct linux_rt_sigreturn_args {
+ char ucp_l_[PADL_(struct l_ucontext *)]; struct l_ucontext * ucp; char ucp_r_[PADR_(struct l_ucontext *)];
+};
+struct linux_ioctl_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)];
+ char arg_l_[PADL_(uintptr_t)]; uintptr_t arg; char arg_r_[PADR_(uintptr_t)];
+};
+struct linux_pread_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char nbyte_l_[PADL_(l_size_t)]; l_size_t nbyte; char nbyte_r_[PADR_(l_size_t)];
+ char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+};
+struct linux_pwrite_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char nbyte_l_[PADL_(l_size_t)]; l_size_t nbyte; char nbyte_r_[PADR_(l_size_t)];
+ char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+};
+struct linux_access_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char amode_l_[PADL_(l_int)]; l_int amode; char amode_r_[PADR_(l_int)];
+};
+struct linux_pipe_args {
+ char pipefds_l_[PADL_(l_ulong *)]; l_ulong * pipefds; char pipefds_r_[PADR_(l_ulong *)];
+};
+struct linux_select_args {
+ char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)];
+ char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)];
+ char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)];
+ char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)];
+ char timeout_l_[PADL_(struct l_timeval *)]; struct l_timeval * timeout; char timeout_r_[PADR_(struct l_timeval *)];
+};
+struct linux_mremap_args {
+ char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)];
+ char old_len_l_[PADL_(l_ulong)]; l_ulong old_len; char old_len_r_[PADR_(l_ulong)];
+ char new_len_l_[PADL_(l_ulong)]; l_ulong new_len; char new_len_r_[PADR_(l_ulong)];
+ char flags_l_[PADL_(l_ulong)]; l_ulong flags; char flags_r_[PADR_(l_ulong)];
+ char new_addr_l_[PADL_(l_ulong)]; l_ulong new_addr; char new_addr_r_[PADR_(l_ulong)];
+};
+struct linux_msync_args {
+ char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)];
+ char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)];
+ char fl_l_[PADL_(l_int)]; l_int fl; char fl_r_[PADR_(l_int)];
+};
+struct linux_mincore_args {
+ char start_l_[PADL_(l_ulong)]; l_ulong start; char start_r_[PADR_(l_ulong)];
+ char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)];
+ char vec_l_[PADL_(u_char *)]; u_char * vec; char vec_r_[PADR_(u_char *)];
+};
+struct linux_shmget_args {
+ char key_l_[PADL_(l_key_t)]; l_key_t key; char key_r_[PADR_(l_key_t)];
+ char size_l_[PADL_(l_size_t)]; l_size_t size; char size_r_[PADR_(l_size_t)];
+ char shmflg_l_[PADL_(l_int)]; l_int shmflg; char shmflg_r_[PADR_(l_int)];
+};
+struct linux_shmat_args {
+ char shmid_l_[PADL_(l_int)]; l_int shmid; char shmid_r_[PADR_(l_int)];
+ char shmaddr_l_[PADL_(char *)]; char * shmaddr; char shmaddr_r_[PADR_(char *)];
+ char shmflg_l_[PADL_(l_int)]; l_int shmflg; char shmflg_r_[PADR_(l_int)];
+};
+struct linux_shmctl_args {
+ char shmid_l_[PADL_(l_int)]; l_int shmid; char shmid_r_[PADR_(l_int)];
+ char cmd_l_[PADL_(l_int)]; l_int cmd; char cmd_r_[PADR_(l_int)];
+ char buf_l_[PADL_(struct l_shmid_ds *)]; struct l_shmid_ds * buf; char buf_r_[PADR_(struct l_shmid_ds *)];
+};
+struct linux_pause_args {
+ register_t dummy;
+};
+struct linux_nanosleep_args {
+ char rqtp_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * rqtp; char rqtp_r_[PADR_(const struct l_timespec *)];
+ char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_getitimer_args {
+ char which_l_[PADL_(l_int)]; l_int which; char which_r_[PADR_(l_int)];
+ char itv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * itv; char itv_r_[PADR_(struct l_itimerval *)];
+};
+struct linux_alarm_args {
+ char secs_l_[PADL_(l_uint)]; l_uint secs; char secs_r_[PADR_(l_uint)];
+};
+struct linux_setitimer_args {
+ char which_l_[PADL_(l_int)]; l_int which; char which_r_[PADR_(l_int)];
+ char itv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * itv; char itv_r_[PADR_(struct l_itimerval *)];
+ char oitv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * oitv; char oitv_r_[PADR_(struct l_itimerval *)];
+};
+struct linux_getpid_args {
+ register_t dummy;
+};
+struct linux_sendfile_args {
+ char out_l_[PADL_(int)]; int out; char out_r_[PADR_(int)];
+ char in_l_[PADL_(int)]; int in; char in_r_[PADR_(int)];
+ char offset_l_[PADL_(l_long *)]; l_long * offset; char offset_r_[PADR_(l_long *)];
+ char count_l_[PADL_(l_size_t)]; l_size_t count; char count_r_[PADR_(l_size_t)];
+};
+struct linux_socket_args {
+ char domain_l_[PADL_(l_int)]; l_int domain; char domain_r_[PADR_(l_int)];
+ char type_l_[PADL_(l_int)]; l_int type; char type_r_[PADR_(l_int)];
+ char protocol_l_[PADL_(l_int)]; l_int protocol; char protocol_r_[PADR_(l_int)];
+};
+struct linux_connect_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char name_l_[PADL_(l_uintptr_t)]; l_uintptr_t name; char name_r_[PADR_(l_uintptr_t)];
+ char namelen_l_[PADL_(l_int)]; l_int namelen; char namelen_r_[PADR_(l_int)];
+};
+struct linux_accept_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char addr_l_[PADL_(l_uintptr_t)]; l_uintptr_t addr; char addr_r_[PADR_(l_uintptr_t)];
+ char namelen_l_[PADL_(l_uintptr_t)]; l_uintptr_t namelen; char namelen_r_[PADR_(l_uintptr_t)];
+};
+struct linux_sendto_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(l_uintptr_t)]; l_uintptr_t msg; char msg_r_[PADR_(l_uintptr_t)];
+ char len_l_[PADL_(l_int)]; l_int len; char len_r_[PADR_(l_int)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char to_l_[PADL_(l_uintptr_t)]; l_uintptr_t to; char to_r_[PADR_(l_uintptr_t)];
+ char tolen_l_[PADL_(l_int)]; l_int tolen; char tolen_r_[PADR_(l_int)];
+};
+struct linux_recvfrom_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char buf_l_[PADL_(l_uintptr_t)]; l_uintptr_t buf; char buf_r_[PADR_(l_uintptr_t)];
+ char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char from_l_[PADL_(l_uintptr_t)]; l_uintptr_t from; char from_r_[PADR_(l_uintptr_t)];
+ char fromlen_l_[PADL_(l_uintptr_t)]; l_uintptr_t fromlen; char fromlen_r_[PADR_(l_uintptr_t)];
+};
+struct linux_sendmsg_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(l_uintptr_t)]; l_uintptr_t msg; char msg_r_[PADR_(l_uintptr_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_recvmsg_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(l_uintptr_t)]; l_uintptr_t msg; char msg_r_[PADR_(l_uintptr_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_shutdown_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char how_l_[PADL_(l_int)]; l_int how; char how_r_[PADR_(l_int)];
+};
+struct linux_bind_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char name_l_[PADL_(l_uintptr_t)]; l_uintptr_t name; char name_r_[PADR_(l_uintptr_t)];
+ char namelen_l_[PADL_(l_int)]; l_int namelen; char namelen_r_[PADR_(l_int)];
+};
+struct linux_listen_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char backlog_l_[PADL_(l_int)]; l_int backlog; char backlog_r_[PADR_(l_int)];
+};
+struct linux_getsockname_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char addr_l_[PADL_(l_uintptr_t)]; l_uintptr_t addr; char addr_r_[PADR_(l_uintptr_t)];
+ char namelen_l_[PADL_(l_uintptr_t)]; l_uintptr_t namelen; char namelen_r_[PADR_(l_uintptr_t)];
+};
+struct linux_getpeername_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char addr_l_[PADL_(l_uintptr_t)]; l_uintptr_t addr; char addr_r_[PADR_(l_uintptr_t)];
+ char namelen_l_[PADL_(l_uintptr_t)]; l_uintptr_t namelen; char namelen_r_[PADR_(l_uintptr_t)];
+};
+struct linux_socketpair_args {
+ char domain_l_[PADL_(l_int)]; l_int domain; char domain_r_[PADR_(l_int)];
+ char type_l_[PADL_(l_int)]; l_int type; char type_r_[PADR_(l_int)];
+ char protocol_l_[PADL_(l_int)]; l_int protocol; char protocol_r_[PADR_(l_int)];
+ char rsv_l_[PADL_(l_uintptr_t)]; l_uintptr_t rsv; char rsv_r_[PADR_(l_uintptr_t)];
+};
+struct linux_setsockopt_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char level_l_[PADL_(l_int)]; l_int level; char level_r_[PADR_(l_int)];
+ char optname_l_[PADL_(l_int)]; l_int optname; char optname_r_[PADR_(l_int)];
+ char optval_l_[PADL_(l_uintptr_t)]; l_uintptr_t optval; char optval_r_[PADR_(l_uintptr_t)];
+ char optlen_l_[PADL_(l_int)]; l_int optlen; char optlen_r_[PADR_(l_int)];
+};
+struct linux_getsockopt_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char level_l_[PADL_(l_int)]; l_int level; char level_r_[PADR_(l_int)];
+ char optname_l_[PADL_(l_int)]; l_int optname; char optname_r_[PADR_(l_int)];
+ char optval_l_[PADL_(l_uintptr_t)]; l_uintptr_t optval; char optval_r_[PADR_(l_uintptr_t)];
+ char optlen_l_[PADL_(l_uintptr_t)]; l_uintptr_t optlen; char optlen_r_[PADR_(l_uintptr_t)];
+};
+struct linux_clone_args {
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char stack_l_[PADL_(void *)]; void * stack; char stack_r_[PADR_(void *)];
+ char parent_tidptr_l_[PADL_(void *)]; void * parent_tidptr; char parent_tidptr_r_[PADR_(void *)];
+ char child_tidptr_l_[PADL_(void *)]; void * child_tidptr; char child_tidptr_r_[PADR_(void *)];
+ char tls_l_[PADL_(void *)]; void * tls; char tls_r_[PADR_(void *)];
+};
+struct linux_fork_args {
+ register_t dummy;
+};
+struct linux_vfork_args {
+ register_t dummy;
+};
+struct linux_execve_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char argp_l_[PADL_(char **)]; char ** argp; char argp_r_[PADR_(char **)];
+ char envp_l_[PADL_(char **)]; char ** envp; char envp_r_[PADR_(char **)];
+};
+struct linux_exit_args {
+ char rval_l_[PADL_(int)]; int rval; char rval_r_[PADR_(int)];
+};
+struct linux_wait4_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char status_l_[PADL_(l_int *)]; l_int * status; char status_r_[PADR_(l_int *)];
+ char options_l_[PADL_(l_int)]; l_int options; char options_r_[PADR_(l_int)];
+ char rusage_l_[PADL_(struct rusage *)]; struct rusage * rusage; char rusage_r_[PADR_(struct rusage *)];
+};
+struct linux_kill_args {
+ char pid_l_[PADL_(l_int)]; l_int pid; char pid_r_[PADR_(l_int)];
+ char signum_l_[PADL_(l_int)]; l_int signum; char signum_r_[PADR_(l_int)];
+};
+struct linux_newuname_args {
+ char buf_l_[PADL_(struct l_new_utsname *)]; struct l_new_utsname * buf; char buf_r_[PADR_(struct l_new_utsname *)];
+};
+struct linux_semget_args {
+ char key_l_[PADL_(l_key_t)]; l_key_t key; char key_r_[PADR_(l_key_t)];
+ char nsems_l_[PADL_(l_int)]; l_int nsems; char nsems_r_[PADR_(l_int)];
+ char semflg_l_[PADL_(l_int)]; l_int semflg; char semflg_r_[PADR_(l_int)];
+};
+struct linux_semop_args {
+ char semid_l_[PADL_(l_int)]; l_int semid; char semid_r_[PADR_(l_int)];
+ char tsops_l_[PADL_(struct l_sembuf *)]; struct l_sembuf * tsops; char tsops_r_[PADR_(struct l_sembuf *)];
+ char nsops_l_[PADL_(l_uint)]; l_uint nsops; char nsops_r_[PADR_(l_uint)];
+};
+struct linux_semctl_args {
+ char semid_l_[PADL_(l_int)]; l_int semid; char semid_r_[PADR_(l_int)];
+ char semnum_l_[PADL_(l_int)]; l_int semnum; char semnum_r_[PADR_(l_int)];
+ char cmd_l_[PADL_(l_int)]; l_int cmd; char cmd_r_[PADR_(l_int)];
+ char arg_l_[PADL_(union l_semun)]; union l_semun arg; char arg_r_[PADR_(union l_semun)];
+};
+struct linux_shmdt_args {
+ char shmaddr_l_[PADL_(char *)]; char * shmaddr; char shmaddr_r_[PADR_(char *)];
+};
+struct linux_msgget_args {
+ char key_l_[PADL_(l_key_t)]; l_key_t key; char key_r_[PADR_(l_key_t)];
+ char msgflg_l_[PADL_(l_int)]; l_int msgflg; char msgflg_r_[PADR_(l_int)];
+};
+struct linux_msgsnd_args {
+ char msqid_l_[PADL_(l_int)]; l_int msqid; char msqid_r_[PADR_(l_int)];
+ char msgp_l_[PADL_(struct l_msgbuf *)]; struct l_msgbuf * msgp; char msgp_r_[PADR_(struct l_msgbuf *)];
+ char msgsz_l_[PADL_(l_size_t)]; l_size_t msgsz; char msgsz_r_[PADR_(l_size_t)];
+ char msgflg_l_[PADL_(l_int)]; l_int msgflg; char msgflg_r_[PADR_(l_int)];
+};
+struct linux_msgrcv_args {
+ char msqid_l_[PADL_(l_int)]; l_int msqid; char msqid_r_[PADR_(l_int)];
+ char msgp_l_[PADL_(struct l_msgbuf *)]; struct l_msgbuf * msgp; char msgp_r_[PADR_(struct l_msgbuf *)];
+ char msgsz_l_[PADL_(l_size_t)]; l_size_t msgsz; char msgsz_r_[PADR_(l_size_t)];
+ char msgtyp_l_[PADL_(l_long)]; l_long msgtyp; char msgtyp_r_[PADR_(l_long)];
+ char msgflg_l_[PADL_(l_int)]; l_int msgflg; char msgflg_r_[PADR_(l_int)];
+};
+struct linux_msgctl_args {
+ char msqid_l_[PADL_(l_int)]; l_int msqid; char msqid_r_[PADR_(l_int)];
+ char cmd_l_[PADL_(l_int)]; l_int cmd; char cmd_r_[PADR_(l_int)];
+ char buf_l_[PADL_(struct l_msqid_ds *)]; struct l_msqid_ds * buf; char buf_r_[PADR_(struct l_msqid_ds *)];
+};
+struct linux_fcntl_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)];
+ char arg_l_[PADL_(l_ulong)]; l_ulong arg; char arg_r_[PADR_(l_ulong)];
+};
+struct linux_fdatasync_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+};
+struct linux_truncate_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char length_l_[PADL_(l_ulong)]; l_ulong length; char length_r_[PADR_(l_ulong)];
+};
+struct linux_ftruncate_args {
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char length_l_[PADL_(l_long)]; l_long length; char length_r_[PADR_(l_long)];
+};
+struct linux_getdents_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char dent_l_[PADL_(void *)]; void * dent; char dent_r_[PADR_(void *)];
+ char count_l_[PADL_(l_uint)]; l_uint count; char count_r_[PADR_(l_uint)];
+};
+struct linux_getcwd_args {
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char bufsize_l_[PADL_(l_ulong)]; l_ulong bufsize; char bufsize_r_[PADR_(l_ulong)];
+};
+struct linux_chdir_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+};
+struct linux_rename_args {
+ char from_l_[PADL_(char *)]; char * from; char from_r_[PADR_(char *)];
+ char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)];
+};
+struct linux_mkdir_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+};
+struct linux_rmdir_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+};
+struct linux_creat_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+};
+struct linux_link_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)];
+};
+struct linux_unlink_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+};
+struct linux_symlink_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)];
+};
+struct linux_readlink_args {
+ char name_l_[PADL_(char *)]; char * name; char name_r_[PADR_(char *)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char count_l_[PADL_(l_int)]; l_int count; char count_r_[PADR_(l_int)];
+};
+struct linux_chmod_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char mode_l_[PADL_(l_mode_t)]; l_mode_t mode; char mode_r_[PADR_(l_mode_t)];
+};
+struct linux_chown_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)];
+ char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)];
+};
+struct linux_lchown_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)];
+ char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)];
+};
+struct linux_getrlimit_args {
+ char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)];
+ char rlim_l_[PADL_(struct l_rlimit *)]; struct l_rlimit * rlim; char rlim_r_[PADR_(struct l_rlimit *)];
+};
+struct linux_sysinfo_args {
+ char info_l_[PADL_(struct l_sysinfo *)]; struct l_sysinfo * info; char info_r_[PADR_(struct l_sysinfo *)];
+};
+struct linux_times_args {
+ char buf_l_[PADL_(struct l_times_argv *)]; struct l_times_argv * buf; char buf_r_[PADR_(struct l_times_argv *)];
+};
+struct linux_ptrace_args {
+ char req_l_[PADL_(l_long)]; l_long req; char req_r_[PADR_(l_long)];
+ char pid_l_[PADL_(l_long)]; l_long pid; char pid_r_[PADR_(l_long)];
+ char addr_l_[PADL_(l_long)]; l_long addr; char addr_r_[PADR_(l_long)];
+ char data_l_[PADL_(l_long)]; l_long data; char data_r_[PADR_(l_long)];
+};
+struct linux_getuid_args {
+ register_t dummy;
+};
+struct linux_syslog_args {
+ char type_l_[PADL_(l_int)]; l_int type; char type_r_[PADR_(l_int)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char len_l_[PADL_(l_int)]; l_int len; char len_r_[PADR_(l_int)];
+};
+struct linux_getgid_args {
+ register_t dummy;
+};
+struct linux_getppid_args {
+ register_t dummy;
+};
+struct linux_getgroups_args {
+ char gidsetsize_l_[PADL_(l_int)]; l_int gidsetsize; char gidsetsize_r_[PADR_(l_int)];
+ char grouplist_l_[PADL_(l_gid_t *)]; l_gid_t * grouplist; char grouplist_r_[PADR_(l_gid_t *)];
+};
+struct linux_setgroups_args {
+ char gidsetsize_l_[PADL_(l_int)]; l_int gidsetsize; char gidsetsize_r_[PADR_(l_int)];
+ char grouplist_l_[PADL_(l_gid_t *)]; l_gid_t * grouplist; char grouplist_r_[PADR_(l_gid_t *)];
+};
+struct linux_setfsuid_args {
+ char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)];
+};
+struct linux_setfsgid_args {
+ char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)];
+};
+struct linux_getsid_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+};
+struct linux_capget_args {
+ char hdrp_l_[PADL_(struct l_user_cap_header *)]; struct l_user_cap_header * hdrp; char hdrp_r_[PADR_(struct l_user_cap_header *)];
+ char datap_l_[PADL_(struct l_user_cap_data *)]; struct l_user_cap_data * datap; char datap_r_[PADR_(struct l_user_cap_data *)];
+};
+struct linux_capset_args {
+ char hdrp_l_[PADL_(struct l_user_cap_header *)]; struct l_user_cap_header * hdrp; char hdrp_r_[PADR_(struct l_user_cap_header *)];
+ char datap_l_[PADL_(struct l_user_cap_data *)]; struct l_user_cap_data * datap; char datap_r_[PADR_(struct l_user_cap_data *)];
+};
+struct linux_rt_sigpending_args {
+ char set_l_[PADL_(l_sigset_t *)]; l_sigset_t * set; char set_r_[PADR_(l_sigset_t *)];
+ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
+};
+struct linux_rt_sigtimedwait_args {
+ char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
+ char ptr_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * ptr; char ptr_r_[PADR_(l_siginfo_t *)];
+ char timeout_l_[PADL_(struct l_timeval *)]; struct l_timeval * timeout; char timeout_r_[PADR_(struct l_timeval *)];
+ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
+};
+struct linux_rt_sigqueueinfo_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
+ char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)];
+};
+struct linux_rt_sigsuspend_args {
+ char newset_l_[PADL_(l_sigset_t *)]; l_sigset_t * newset; char newset_r_[PADR_(l_sigset_t *)];
+ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
+};
+struct linux_sigaltstack_args {
+ char uss_l_[PADL_(l_stack_t *)]; l_stack_t * uss; char uss_r_[PADR_(l_stack_t *)];
+ char uoss_l_[PADL_(l_stack_t *)]; l_stack_t * uoss; char uoss_r_[PADR_(l_stack_t *)];
+};
+struct linux_utime_args {
+ char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)];
+ char times_l_[PADL_(struct l_utimbuf *)]; struct l_utimbuf * times; char times_r_[PADR_(struct l_utimbuf *)];
+};
+struct linux_mknod_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+ char dev_l_[PADL_(l_dev_t)]; l_dev_t dev; char dev_r_[PADR_(l_dev_t)];
+};
+struct linux_personality_args {
+ char per_l_[PADL_(l_ulong)]; l_ulong per; char per_r_[PADR_(l_ulong)];
+};
+struct linux_ustat_args {
+ char dev_l_[PADL_(l_dev_t)]; l_dev_t dev; char dev_r_[PADR_(l_dev_t)];
+ char ubuf_l_[PADL_(struct l_ustat *)]; struct l_ustat * ubuf; char ubuf_r_[PADR_(struct l_ustat *)];
+};
+struct linux_statfs_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char buf_l_[PADL_(struct l_statfs_buf *)]; struct l_statfs_buf * buf; char buf_r_[PADR_(struct l_statfs_buf *)];
+};
+struct linux_fstatfs_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char buf_l_[PADL_(struct l_statfs_buf *)]; struct l_statfs_buf * buf; char buf_r_[PADR_(struct l_statfs_buf *)];
+};
+struct linux_sysfs_args {
+ char option_l_[PADL_(l_int)]; l_int option; char option_r_[PADR_(l_int)];
+ char arg1_l_[PADL_(l_ulong)]; l_ulong arg1; char arg1_r_[PADR_(l_ulong)];
+ char arg2_l_[PADL_(l_ulong)]; l_ulong arg2; char arg2_r_[PADR_(l_ulong)];
+};
+struct linux_getpriority_args {
+ char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
+ char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)];
+};
+struct linux_sched_setparam_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)];
+};
+struct linux_sched_getparam_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)];
+};
+struct linux_sched_setscheduler_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
+ char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)];
+};
+struct linux_sched_getscheduler_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+};
+struct linux_sched_get_priority_max_args {
+ char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
+};
+struct linux_sched_get_priority_min_args {
+ char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
+};
+struct linux_sched_rr_get_interval_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char interval_l_[PADL_(struct l_timespec *)]; struct l_timespec * interval; char interval_r_[PADR_(struct l_timespec *)];
+};
+struct linux_vhangup_args {
+ register_t dummy;
+};
+struct linux_pivot_root_args {
+ register_t dummy;
+};
+struct linux_sysctl_args {
+ char args_l_[PADL_(struct l___sysctl_args *)]; struct l___sysctl_args * args; char args_r_[PADR_(struct l___sysctl_args *)];
+};
+struct linux_prctl_args {
+ char option_l_[PADL_(l_int)]; l_int option; char option_r_[PADR_(l_int)];
+ char arg2_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg2; char arg2_r_[PADR_(l_uintptr_t)];
+ char arg3_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg3; char arg3_r_[PADR_(l_uintptr_t)];
+ char arg4_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg4; char arg4_r_[PADR_(l_uintptr_t)];
+ char arg5_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg5; char arg5_r_[PADR_(l_uintptr_t)];
+};
+struct linux_arch_prctl_args {
+ char code_l_[PADL_(l_int)]; l_int code; char code_r_[PADR_(l_int)];
+ char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)];
+};
+struct linux_adjtimex_args {
+ register_t dummy;
+};
+struct linux_setrlimit_args {
+ char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)];
+ char rlim_l_[PADL_(struct l_rlimit *)]; struct l_rlimit * rlim; char rlim_r_[PADR_(struct l_rlimit *)];
+};
+struct linux_mount_args {
+ char specialfile_l_[PADL_(char *)]; char * specialfile; char specialfile_r_[PADR_(char *)];
+ char dir_l_[PADL_(char *)]; char * dir; char dir_r_[PADR_(char *)];
+ char filesystemtype_l_[PADL_(char *)]; char * filesystemtype; char filesystemtype_r_[PADR_(char *)];
+ char rwflag_l_[PADL_(l_ulong)]; l_ulong rwflag; char rwflag_r_[PADR_(l_ulong)];
+ char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)];
+};
+struct linux_umount_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_swapoff_args {
+ register_t dummy;
+};
+struct linux_reboot_args {
+ char magic1_l_[PADL_(l_int)]; l_int magic1; char magic1_r_[PADR_(l_int)];
+ char magic2_l_[PADL_(l_int)]; l_int magic2; char magic2_r_[PADR_(l_int)];
+ char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)];
+ char arg_l_[PADL_(void *)]; void * arg; char arg_r_[PADR_(void *)];
+};
+struct linux_sethostname_args {
+ char hostname_l_[PADL_(char *)]; char * hostname; char hostname_r_[PADR_(char *)];
+ char len_l_[PADL_(l_uint)]; l_uint len; char len_r_[PADR_(l_uint)];
+};
+struct linux_setdomainname_args {
+ char name_l_[PADL_(char *)]; char * name; char name_r_[PADR_(char *)];
+ char len_l_[PADL_(l_int)]; l_int len; char len_r_[PADR_(l_int)];
+};
+struct linux_iopl_args {
+ char level_l_[PADL_(l_uint)]; l_uint level; char level_r_[PADR_(l_uint)];
+};
+struct linux_create_module_args {
+ register_t dummy;
+};
+struct linux_init_module_args {
+ register_t dummy;
+};
+struct linux_delete_module_args {
+ register_t dummy;
+};
+struct linux_get_kernel_syms_args {
+ register_t dummy;
+};
+struct linux_query_module_args {
+ register_t dummy;
+};
+struct linux_quotactl_args {
+ register_t dummy;
+};
+struct linux_nfsservctl_args {
+ register_t dummy;
+};
+struct linux_getpmsg_args {
+ register_t dummy;
+};
+struct linux_putpmsg_args {
+ register_t dummy;
+};
+struct linux_afs_syscall_args {
+ register_t dummy;
+};
+struct linux_tuxcall_args {
+ register_t dummy;
+};
+struct linux_security_args {
+ register_t dummy;
+};
+struct linux_gettid_args {
+ register_t dummy;
+};
+struct linux_setxattr_args {
+ register_t dummy;
+};
+struct linux_lsetxattr_args {
+ register_t dummy;
+};
+struct linux_fsetxattr_args {
+ register_t dummy;
+};
+struct linux_getxattr_args {
+ register_t dummy;
+};
+struct linux_lgetxattr_args {
+ register_t dummy;
+};
+struct linux_fgetxattr_args {
+ register_t dummy;
+};
+struct linux_listxattr_args {
+ register_t dummy;
+};
+struct linux_llistxattr_args {
+ register_t dummy;
+};
+struct linux_flistxattr_args {
+ register_t dummy;
+};
+struct linux_removexattr_args {
+ register_t dummy;
+};
+struct linux_lremovexattr_args {
+ register_t dummy;
+};
+struct linux_fremovexattr_args {
+ register_t dummy;
+};
+struct linux_tkill_args {
+ char tid_l_[PADL_(int)]; int tid; char tid_r_[PADR_(int)];
+ char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
+};
+struct linux_time_args {
+ char tm_l_[PADL_(l_time_t *)]; l_time_t * tm; char tm_r_[PADR_(l_time_t *)];
+};
+struct linux_sys_futex_args {
+ char uaddr_l_[PADL_(void *)]; void * uaddr; char uaddr_r_[PADR_(void *)];
+ char op_l_[PADL_(int)]; int op; char op_r_[PADR_(int)];
+ char val_l_[PADL_(int)]; int val; char val_r_[PADR_(int)];
+ char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
+ char uaddr2_l_[PADL_(void *)]; void * uaddr2; char uaddr2_r_[PADR_(void *)];
+ char val3_l_[PADL_(int)]; int val3; char val3_r_[PADR_(int)];
+};
+struct linux_sched_setaffinity_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char len_l_[PADL_(l_uint)]; l_uint len; char len_r_[PADR_(l_uint)];
+ char user_mask_ptr_l_[PADL_(l_ulong *)]; l_ulong * user_mask_ptr; char user_mask_ptr_r_[PADR_(l_ulong *)];
+};
+struct linux_sched_getaffinity_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char len_l_[PADL_(l_uint)]; l_uint len; char len_r_[PADR_(l_uint)];
+ char user_mask_ptr_l_[PADL_(l_ulong *)]; l_ulong * user_mask_ptr; char user_mask_ptr_r_[PADR_(l_ulong *)];
+};
+struct linux_set_thread_area_args {
+ register_t dummy;
+};
+struct linux_lookup_dcookie_args {
+ register_t dummy;
+};
+struct linux_epoll_create_args {
+ char size_l_[PADL_(l_int)]; l_int size; char size_r_[PADR_(l_int)];
+};
+struct linux_epoll_ctl_old_args {
+ register_t dummy;
+};
+struct linux_epoll_wait_old_args {
+ register_t dummy;
+};
+struct linux_remap_file_pages_args {
+ register_t dummy;
+};
+struct linux_getdents64_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char dirent_l_[PADL_(void *)]; void * dirent; char dirent_r_[PADR_(void *)];
+ char count_l_[PADL_(l_uint)]; l_uint count; char count_r_[PADR_(l_uint)];
+};
+struct linux_set_tid_address_args {
+ char tidptr_l_[PADL_(int *)]; int * tidptr; char tidptr_r_[PADR_(int *)];
+};
+struct linux_semtimedop_args {
+ register_t dummy;
+};
+struct linux_fadvise64_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+ char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)];
+ char advice_l_[PADL_(int)]; int advice; char advice_r_[PADR_(int)];
+};
+struct linux_timer_create_args {
+ char clock_id_l_[PADL_(clockid_t)]; clockid_t clock_id; char clock_id_r_[PADR_(clockid_t)];
+ char evp_l_[PADL_(struct sigevent *)]; struct sigevent * evp; char evp_r_[PADR_(struct sigevent *)];
+ char timerid_l_[PADL_(l_timer_t *)]; l_timer_t * timerid; char timerid_r_[PADR_(l_timer_t *)];
+};
+struct linux_timer_settime_args {
+ char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char new_l_[PADL_(const struct itimerspec *)]; const struct itimerspec * new; char new_r_[PADR_(const struct itimerspec *)];
+ char old_l_[PADL_(struct itimerspec *)]; struct itimerspec * old; char old_r_[PADR_(struct itimerspec *)];
+};
+struct linux_timer_gettime_args {
+ char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)];
+ char setting_l_[PADL_(struct itimerspec *)]; struct itimerspec * setting; char setting_r_[PADR_(struct itimerspec *)];
+};
+struct linux_timer_getoverrun_args {
+ char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)];
+};
+struct linux_timer_delete_args {
+ char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)];
+};
+struct linux_clock_settime_args {
+ char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
+ char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_clock_gettime_args {
+ char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
+ char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_clock_getres_args {
+ char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
+ char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_clock_nanosleep_args {
+ char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char rqtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rqtp; char rqtp_r_[PADR_(struct l_timespec *)];
+ char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)];
+};
+struct linux_exit_group_args {
+ char error_code_l_[PADL_(int)]; int error_code; char error_code_r_[PADR_(int)];
+};
+struct linux_epoll_wait_args {
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)];
+ char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)];
+ char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)];
+};
+struct linux_epoll_ctl_args {
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char op_l_[PADL_(l_int)]; l_int op; char op_r_[PADR_(l_int)];
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char event_l_[PADL_(struct epoll_event *)]; struct epoll_event * event; char event_r_[PADR_(struct epoll_event *)];
+};
+struct linux_tgkill_args {
+ char tgid_l_[PADL_(int)]; int tgid; char tgid_r_[PADR_(int)];
+ char pid_l_[PADL_(int)]; int pid; char pid_r_[PADR_(int)];
+ char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)];
+};
+struct linux_utimes_args {
+ char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)];
+ char tptr_l_[PADL_(struct l_timeval *)]; struct l_timeval * tptr; char tptr_r_[PADR_(struct l_timeval *)];
+};
+struct linux_mbind_args {
+ register_t dummy;
+};
+struct linux_set_mempolicy_args {
+ register_t dummy;
+};
+struct linux_get_mempolicy_args {
+ register_t dummy;
+};
+struct linux_mq_open_args {
+ register_t dummy;
+};
+struct linux_mq_unlink_args {
+ register_t dummy;
+};
+struct linux_mq_timedsend_args {
+ register_t dummy;
+};
+struct linux_mq_timedreceive_args {
+ register_t dummy;
+};
+struct linux_mq_notify_args {
+ register_t dummy;
+};
+struct linux_mq_getsetattr_args {
+ register_t dummy;
+};
+struct linux_kexec_load_args {
+ register_t dummy;
+};
+struct linux_waitid_args {
+ char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)];
+ char id_l_[PADL_(l_pid_t)]; l_pid_t id; char id_r_[PADR_(l_pid_t)];
+ char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)];
+ char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)];
+ char rusage_l_[PADL_(struct rusage *)]; struct rusage * rusage; char rusage_r_[PADR_(struct rusage *)];
+};
+struct linux_add_key_args {
+ register_t dummy;
+};
+struct linux_request_key_args {
+ register_t dummy;
+};
+struct linux_keyctl_args {
+ register_t dummy;
+};
+struct linux_ioprio_set_args {
+ register_t dummy;
+};
+struct linux_ioprio_get_args {
+ register_t dummy;
+};
+struct linux_inotify_init_args {
+ register_t dummy;
+};
+struct linux_inotify_add_watch_args {
+ register_t dummy;
+};
+struct linux_inotify_rm_watch_args {
+ register_t dummy;
+};
+struct linux_migrate_pages_args {
+ register_t dummy;
+};
+struct linux_openat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+};
+struct linux_mkdirat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+};
+struct linux_mknodat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+ char dev_l_[PADL_(l_uint)]; l_uint dev; char dev_r_[PADR_(l_uint)];
+};
+struct linux_fchownat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)];
+ char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)];
+ char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)];
+ char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
+};
+struct linux_futimesat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)];
+ char utimes_l_[PADL_(struct l_timeval *)]; struct l_timeval * utimes; char utimes_r_[PADR_(struct l_timeval *)];
+};
+struct linux_newfstatat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char pathname_l_[PADL_(char *)]; char * pathname; char pathname_r_[PADR_(char *)];
+ char statbuf_l_[PADL_(struct l_stat64 *)]; struct l_stat64 * statbuf; char statbuf_r_[PADR_(struct l_stat64 *)];
+ char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
+};
+struct linux_unlinkat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)];
+ char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
+};
+struct linux_renameat_args {
+ char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)];
+ char oldname_l_[PADL_(const char *)]; const char * oldname; char oldname_r_[PADR_(const char *)];
+ char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)];
+ char newname_l_[PADL_(const char *)]; const char * newname; char newname_r_[PADR_(const char *)];
+};
+struct linux_linkat_args {
+ char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)];
+ char oldname_l_[PADL_(const char *)]; const char * oldname; char oldname_r_[PADR_(const char *)];
+ char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)];
+ char newname_l_[PADL_(const char *)]; const char * newname; char newname_r_[PADR_(const char *)];
+ char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
+};
+struct linux_symlinkat_args {
+ char oldname_l_[PADL_(const char *)]; const char * oldname; char oldname_r_[PADR_(const char *)];
+ char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)];
+ char newname_l_[PADL_(const char *)]; const char * newname; char newname_r_[PADR_(const char *)];
+};
+struct linux_readlinkat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char bufsiz_l_[PADL_(l_int)]; l_int bufsiz; char bufsiz_r_[PADR_(l_int)];
+};
+struct linux_fchmodat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)];
+ char mode_l_[PADL_(l_mode_t)]; l_mode_t mode; char mode_r_[PADR_(l_mode_t)];
+};
+struct linux_faccessat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)];
+ char amode_l_[PADL_(l_int)]; l_int amode; char amode_r_[PADR_(l_int)];
+};
+struct linux_pselect6_args {
+ char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)];
+ char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)];
+ char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)];
+ char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)];
+ char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)];
+ char sig_l_[PADL_(l_uintptr_t *)]; l_uintptr_t * sig; char sig_r_[PADR_(l_uintptr_t *)];
+};
+struct linux_ppoll_args {
+ char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)];
+ char nfds_l_[PADL_(uint32_t)]; uint32_t nfds; char nfds_r_[PADR_(uint32_t)];
+ char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)];
+ char sset_l_[PADL_(l_sigset_t *)]; l_sigset_t * sset; char sset_r_[PADR_(l_sigset_t *)];
+ char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)];
+};
+struct linux_unshare_args {
+ register_t dummy;
+};
+struct linux_set_robust_list_args {
+ char head_l_[PADL_(struct linux_robust_list_head *)]; struct linux_robust_list_head * head; char head_r_[PADR_(struct linux_robust_list_head *)];
+ char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)];
+};
+struct linux_get_robust_list_args {
+ char pid_l_[PADL_(l_int)]; l_int pid; char pid_r_[PADR_(l_int)];
+ char head_l_[PADL_(struct linux_robust_list_head *)]; struct linux_robust_list_head * head; char head_r_[PADR_(struct linux_robust_list_head *)];
+ char len_l_[PADL_(l_size_t *)]; l_size_t * len; char len_r_[PADR_(l_size_t *)];
+};
+struct linux_splice_args {
+ register_t dummy;
+};
+struct linux_tee_args {
+ register_t dummy;
+};
+struct linux_sync_file_range_args {
+ register_t dummy;
+};
+struct linux_vmsplice_args {
+ register_t dummy;
+};
+struct linux_move_pages_args {
+ register_t dummy;
+};
+struct linux_utimensat_args {
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)];
+ char times_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * times; char times_r_[PADR_(const struct l_timespec *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_epoll_pwait_args {
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)];
+ char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)];
+ char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)];
+ char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
+};
+struct linux_signalfd_args {
+ register_t dummy;
+};
+struct linux_timerfd_args {
+ register_t dummy;
+};
+struct linux_eventfd_args {
+ char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)];
+};
+struct linux_fallocate_args {
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+ char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+ char len_l_[PADL_(l_loff_t)]; l_loff_t len; char len_r_[PADR_(l_loff_t)];
+};
+struct linux_timerfd_settime_args {
+ register_t dummy;
+};
+struct linux_timerfd_gettime_args {
+ register_t dummy;
+};
+struct linux_accept4_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char addr_l_[PADL_(l_uintptr_t)]; l_uintptr_t addr; char addr_r_[PADR_(l_uintptr_t)];
+ char namelen_l_[PADL_(l_uintptr_t)]; l_uintptr_t namelen; char namelen_r_[PADR_(l_uintptr_t)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+};
+struct linux_signalfd4_args {
+ register_t dummy;
+};
+struct linux_eventfd2_args {
+ char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_epoll_create1_args {
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_dup3_args {
+ char oldfd_l_[PADL_(l_int)]; l_int oldfd; char oldfd_r_[PADR_(l_int)];
+ char newfd_l_[PADL_(l_int)]; l_int newfd; char newfd_r_[PADR_(l_int)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_pipe2_args {
+ char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_inotify_init1_args {
+ register_t dummy;
+};
+struct linux_preadv_args {
+ register_t dummy;
+};
+struct linux_pwritev_args {
+ register_t dummy;
+};
+struct linux_rt_tsigqueueinfo_args {
+ register_t dummy;
+};
+struct linux_perf_event_open_args {
+ register_t dummy;
+};
+struct linux_recvmmsg_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)];
+ char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
+ char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
+};
+struct linux_fanotify_init_args {
+ register_t dummy;
+};
+struct linux_fanotify_mark_args {
+ register_t dummy;
+};
+struct linux_prlimit64_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)];
+ char new_l_[PADL_(struct rlimit *)]; struct rlimit * new; char new_r_[PADR_(struct rlimit *)];
+ char old_l_[PADL_(struct rlimit *)]; struct rlimit * old; char old_r_[PADR_(struct rlimit *)];
+};
+struct linux_name_to_handle_at_args {
+ register_t dummy;
+};
+struct linux_open_by_handle_at_args {
+ register_t dummy;
+};
+struct linux_clock_adjtime_args {
+ register_t dummy;
+};
+struct linux_syncfs_args {
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+};
+struct linux_sendmmsg_args {
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)];
+ char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
+};
+struct linux_setns_args {
+ register_t dummy;
+};
+struct linux_process_vm_readv_args {
+ register_t dummy;
+};
+struct linux_process_vm_writev_args {
+ register_t dummy;
+};
+struct linux_kcmp_args {
+ register_t dummy;
+};
+struct linux_finit_module_args {
+ register_t dummy;
+};
+#define nosys linux_nosys
+int linux_open(struct thread *, struct linux_open_args *);
+int linux_newstat(struct thread *, struct linux_newstat_args *);
+int linux_newfstat(struct thread *, struct linux_newfstat_args *);
+int linux_newlstat(struct thread *, struct linux_newlstat_args *);
+int linux_lseek(struct thread *, struct linux_lseek_args *);
+int linux_mmap2(struct thread *, struct linux_mmap2_args *);
+int linux_mprotect(struct thread *, struct linux_mprotect_args *);
+int linux_brk(struct thread *, struct linux_brk_args *);
+int linux_rt_sigaction(struct thread *, struct linux_rt_sigaction_args *);
+int linux_rt_sigprocmask(struct thread *, struct linux_rt_sigprocmask_args *);
+int linux_rt_sigreturn(struct thread *, struct linux_rt_sigreturn_args *);
+int linux_ioctl(struct thread *, struct linux_ioctl_args *);
+int linux_pread(struct thread *, struct linux_pread_args *);
+int linux_pwrite(struct thread *, struct linux_pwrite_args *);
+int linux_access(struct thread *, struct linux_access_args *);
+int linux_pipe(struct thread *, struct linux_pipe_args *);
+int linux_select(struct thread *, struct linux_select_args *);
+int linux_mremap(struct thread *, struct linux_mremap_args *);
+int linux_msync(struct thread *, struct linux_msync_args *);
+int linux_mincore(struct thread *, struct linux_mincore_args *);
+int linux_shmget(struct thread *, struct linux_shmget_args *);
+int linux_shmat(struct thread *, struct linux_shmat_args *);
+int linux_shmctl(struct thread *, struct linux_shmctl_args *);
+int linux_pause(struct thread *, struct linux_pause_args *);
+int linux_nanosleep(struct thread *, struct linux_nanosleep_args *);
+int linux_getitimer(struct thread *, struct linux_getitimer_args *);
+int linux_alarm(struct thread *, struct linux_alarm_args *);
+int linux_setitimer(struct thread *, struct linux_setitimer_args *);
+int linux_getpid(struct thread *, struct linux_getpid_args *);
+int linux_sendfile(struct thread *, struct linux_sendfile_args *);
+int linux_socket(struct thread *, struct linux_socket_args *);
+int linux_connect(struct thread *, struct linux_connect_args *);
+int linux_accept(struct thread *, struct linux_accept_args *);
+int linux_sendto(struct thread *, struct linux_sendto_args *);
+int linux_recvfrom(struct thread *, struct linux_recvfrom_args *);
+int linux_sendmsg(struct thread *, struct linux_sendmsg_args *);
+int linux_recvmsg(struct thread *, struct linux_recvmsg_args *);
+int linux_shutdown(struct thread *, struct linux_shutdown_args *);
+int linux_bind(struct thread *, struct linux_bind_args *);
+int linux_listen(struct thread *, struct linux_listen_args *);
+int linux_getsockname(struct thread *, struct linux_getsockname_args *);
+int linux_getpeername(struct thread *, struct linux_getpeername_args *);
+int linux_socketpair(struct thread *, struct linux_socketpair_args *);
+int linux_setsockopt(struct thread *, struct linux_setsockopt_args *);
+int linux_getsockopt(struct thread *, struct linux_getsockopt_args *);
+int linux_clone(struct thread *, struct linux_clone_args *);
+int linux_fork(struct thread *, struct linux_fork_args *);
+int linux_vfork(struct thread *, struct linux_vfork_args *);
+int linux_execve(struct thread *, struct linux_execve_args *);
+int linux_exit(struct thread *, struct linux_exit_args *);
+int linux_wait4(struct thread *, struct linux_wait4_args *);
+int linux_kill(struct thread *, struct linux_kill_args *);
+int linux_newuname(struct thread *, struct linux_newuname_args *);
+int linux_semget(struct thread *, struct linux_semget_args *);
+int linux_semop(struct thread *, struct linux_semop_args *);
+int linux_semctl(struct thread *, struct linux_semctl_args *);
+int linux_shmdt(struct thread *, struct linux_shmdt_args *);
+int linux_msgget(struct thread *, struct linux_msgget_args *);
+int linux_msgsnd(struct thread *, struct linux_msgsnd_args *);
+int linux_msgrcv(struct thread *, struct linux_msgrcv_args *);
+int linux_msgctl(struct thread *, struct linux_msgctl_args *);
+int linux_fcntl(struct thread *, struct linux_fcntl_args *);
+int linux_fdatasync(struct thread *, struct linux_fdatasync_args *);
+int linux_truncate(struct thread *, struct linux_truncate_args *);
+int linux_ftruncate(struct thread *, struct linux_ftruncate_args *);
+int linux_getdents(struct thread *, struct linux_getdents_args *);
+int linux_getcwd(struct thread *, struct linux_getcwd_args *);
+int linux_chdir(struct thread *, struct linux_chdir_args *);
+int linux_rename(struct thread *, struct linux_rename_args *);
+int linux_mkdir(struct thread *, struct linux_mkdir_args *);
+int linux_rmdir(struct thread *, struct linux_rmdir_args *);
+int linux_creat(struct thread *, struct linux_creat_args *);
+int linux_link(struct thread *, struct linux_link_args *);
+int linux_unlink(struct thread *, struct linux_unlink_args *);
+int linux_symlink(struct thread *, struct linux_symlink_args *);
+int linux_readlink(struct thread *, struct linux_readlink_args *);
+int linux_chmod(struct thread *, struct linux_chmod_args *);
+int linux_chown(struct thread *, struct linux_chown_args *);
+int linux_lchown(struct thread *, struct linux_lchown_args *);
+int linux_getrlimit(struct thread *, struct linux_getrlimit_args *);
+int linux_sysinfo(struct thread *, struct linux_sysinfo_args *);
+int linux_times(struct thread *, struct linux_times_args *);
+int linux_ptrace(struct thread *, struct linux_ptrace_args *);
+int linux_getuid(struct thread *, struct linux_getuid_args *);
+int linux_syslog(struct thread *, struct linux_syslog_args *);
+int linux_getgid(struct thread *, struct linux_getgid_args *);
+int linux_getppid(struct thread *, struct linux_getppid_args *);
+int linux_getgroups(struct thread *, struct linux_getgroups_args *);
+int linux_setgroups(struct thread *, struct linux_setgroups_args *);
+int linux_setfsuid(struct thread *, struct linux_setfsuid_args *);
+int linux_setfsgid(struct thread *, struct linux_setfsgid_args *);
+int linux_getsid(struct thread *, struct linux_getsid_args *);
+int linux_capget(struct thread *, struct linux_capget_args *);
+int linux_capset(struct thread *, struct linux_capset_args *);
+int linux_rt_sigpending(struct thread *, struct linux_rt_sigpending_args *);
+int linux_rt_sigtimedwait(struct thread *, struct linux_rt_sigtimedwait_args *);
+int linux_rt_sigqueueinfo(struct thread *, struct linux_rt_sigqueueinfo_args *);
+int linux_rt_sigsuspend(struct thread *, struct linux_rt_sigsuspend_args *);
+int linux_sigaltstack(struct thread *, struct linux_sigaltstack_args *);
+int linux_utime(struct thread *, struct linux_utime_args *);
+int linux_mknod(struct thread *, struct linux_mknod_args *);
+int linux_personality(struct thread *, struct linux_personality_args *);
+int linux_ustat(struct thread *, struct linux_ustat_args *);
+int linux_statfs(struct thread *, struct linux_statfs_args *);
+int linux_fstatfs(struct thread *, struct linux_fstatfs_args *);
+int linux_sysfs(struct thread *, struct linux_sysfs_args *);
+int linux_getpriority(struct thread *, struct linux_getpriority_args *);
+int linux_sched_setparam(struct thread *, struct linux_sched_setparam_args *);
+int linux_sched_getparam(struct thread *, struct linux_sched_getparam_args *);
+int linux_sched_setscheduler(struct thread *, struct linux_sched_setscheduler_args *);
+int linux_sched_getscheduler(struct thread *, struct linux_sched_getscheduler_args *);
+int linux_sched_get_priority_max(struct thread *, struct linux_sched_get_priority_max_args *);
+int linux_sched_get_priority_min(struct thread *, struct linux_sched_get_priority_min_args *);
+int linux_sched_rr_get_interval(struct thread *, struct linux_sched_rr_get_interval_args *);
+int linux_vhangup(struct thread *, struct linux_vhangup_args *);
+int linux_pivot_root(struct thread *, struct linux_pivot_root_args *);
+int linux_sysctl(struct thread *, struct linux_sysctl_args *);
+int linux_prctl(struct thread *, struct linux_prctl_args *);
+int linux_arch_prctl(struct thread *, struct linux_arch_prctl_args *);
+int linux_adjtimex(struct thread *, struct linux_adjtimex_args *);
+int linux_setrlimit(struct thread *, struct linux_setrlimit_args *);
+int linux_mount(struct thread *, struct linux_mount_args *);
+int linux_umount(struct thread *, struct linux_umount_args *);
+int linux_swapoff(struct thread *, struct linux_swapoff_args *);
+int linux_reboot(struct thread *, struct linux_reboot_args *);
+int linux_sethostname(struct thread *, struct linux_sethostname_args *);
+int linux_setdomainname(struct thread *, struct linux_setdomainname_args *);
+int linux_iopl(struct thread *, struct linux_iopl_args *);
+int linux_create_module(struct thread *, struct linux_create_module_args *);
+int linux_init_module(struct thread *, struct linux_init_module_args *);
+int linux_delete_module(struct thread *, struct linux_delete_module_args *);
+int linux_get_kernel_syms(struct thread *, struct linux_get_kernel_syms_args *);
+int linux_query_module(struct thread *, struct linux_query_module_args *);
+int linux_quotactl(struct thread *, struct linux_quotactl_args *);
+int linux_nfsservctl(struct thread *, struct linux_nfsservctl_args *);
+int linux_getpmsg(struct thread *, struct linux_getpmsg_args *);
+int linux_putpmsg(struct thread *, struct linux_putpmsg_args *);
+int linux_afs_syscall(struct thread *, struct linux_afs_syscall_args *);
+int linux_tuxcall(struct thread *, struct linux_tuxcall_args *);
+int linux_security(struct thread *, struct linux_security_args *);
+int linux_gettid(struct thread *, struct linux_gettid_args *);
+int linux_setxattr(struct thread *, struct linux_setxattr_args *);
+int linux_lsetxattr(struct thread *, struct linux_lsetxattr_args *);
+int linux_fsetxattr(struct thread *, struct linux_fsetxattr_args *);
+int linux_getxattr(struct thread *, struct linux_getxattr_args *);
+int linux_lgetxattr(struct thread *, struct linux_lgetxattr_args *);
+int linux_fgetxattr(struct thread *, struct linux_fgetxattr_args *);
+int linux_listxattr(struct thread *, struct linux_listxattr_args *);
+int linux_llistxattr(struct thread *, struct linux_llistxattr_args *);
+int linux_flistxattr(struct thread *, struct linux_flistxattr_args *);
+int linux_removexattr(struct thread *, struct linux_removexattr_args *);
+int linux_lremovexattr(struct thread *, struct linux_lremovexattr_args *);
+int linux_fremovexattr(struct thread *, struct linux_fremovexattr_args *);
+int linux_tkill(struct thread *, struct linux_tkill_args *);
+int linux_time(struct thread *, struct linux_time_args *);
+int linux_sys_futex(struct thread *, struct linux_sys_futex_args *);
+int linux_sched_setaffinity(struct thread *, struct linux_sched_setaffinity_args *);
+int linux_sched_getaffinity(struct thread *, struct linux_sched_getaffinity_args *);
+int linux_set_thread_area(struct thread *, struct linux_set_thread_area_args *);
+int linux_lookup_dcookie(struct thread *, struct linux_lookup_dcookie_args *);
+int linux_epoll_create(struct thread *, struct linux_epoll_create_args *);
+int linux_epoll_ctl_old(struct thread *, struct linux_epoll_ctl_old_args *);
+int linux_epoll_wait_old(struct thread *, struct linux_epoll_wait_old_args *);
+int linux_remap_file_pages(struct thread *, struct linux_remap_file_pages_args *);
+int linux_getdents64(struct thread *, struct linux_getdents64_args *);
+int linux_set_tid_address(struct thread *, struct linux_set_tid_address_args *);
+int linux_semtimedop(struct thread *, struct linux_semtimedop_args *);
+int linux_fadvise64(struct thread *, struct linux_fadvise64_args *);
+int linux_timer_create(struct thread *, struct linux_timer_create_args *);
+int linux_timer_settime(struct thread *, struct linux_timer_settime_args *);
+int linux_timer_gettime(struct thread *, struct linux_timer_gettime_args *);
+int linux_timer_getoverrun(struct thread *, struct linux_timer_getoverrun_args *);
+int linux_timer_delete(struct thread *, struct linux_timer_delete_args *);
+int linux_clock_settime(struct thread *, struct linux_clock_settime_args *);
+int linux_clock_gettime(struct thread *, struct linux_clock_gettime_args *);
+int linux_clock_getres(struct thread *, struct linux_clock_getres_args *);
+int linux_clock_nanosleep(struct thread *, struct linux_clock_nanosleep_args *);
+int linux_exit_group(struct thread *, struct linux_exit_group_args *);
+int linux_epoll_wait(struct thread *, struct linux_epoll_wait_args *);
+int linux_epoll_ctl(struct thread *, struct linux_epoll_ctl_args *);
+int linux_tgkill(struct thread *, struct linux_tgkill_args *);
+int linux_utimes(struct thread *, struct linux_utimes_args *);
+int linux_mbind(struct thread *, struct linux_mbind_args *);
+int linux_set_mempolicy(struct thread *, struct linux_set_mempolicy_args *);
+int linux_get_mempolicy(struct thread *, struct linux_get_mempolicy_args *);
+int linux_mq_open(struct thread *, struct linux_mq_open_args *);
+int linux_mq_unlink(struct thread *, struct linux_mq_unlink_args *);
+int linux_mq_timedsend(struct thread *, struct linux_mq_timedsend_args *);
+int linux_mq_timedreceive(struct thread *, struct linux_mq_timedreceive_args *);
+int linux_mq_notify(struct thread *, struct linux_mq_notify_args *);
+int linux_mq_getsetattr(struct thread *, struct linux_mq_getsetattr_args *);
+int linux_kexec_load(struct thread *, struct linux_kexec_load_args *);
+int linux_waitid(struct thread *, struct linux_waitid_args *);
+int linux_add_key(struct thread *, struct linux_add_key_args *);
+int linux_request_key(struct thread *, struct linux_request_key_args *);
+int linux_keyctl(struct thread *, struct linux_keyctl_args *);
+int linux_ioprio_set(struct thread *, struct linux_ioprio_set_args *);
+int linux_ioprio_get(struct thread *, struct linux_ioprio_get_args *);
+int linux_inotify_init(struct thread *, struct linux_inotify_init_args *);
+int linux_inotify_add_watch(struct thread *, struct linux_inotify_add_watch_args *);
+int linux_inotify_rm_watch(struct thread *, struct linux_inotify_rm_watch_args *);
+int linux_migrate_pages(struct thread *, struct linux_migrate_pages_args *);
+int linux_openat(struct thread *, struct linux_openat_args *);
+int linux_mkdirat(struct thread *, struct linux_mkdirat_args *);
+int linux_mknodat(struct thread *, struct linux_mknodat_args *);
+int linux_fchownat(struct thread *, struct linux_fchownat_args *);
+int linux_futimesat(struct thread *, struct linux_futimesat_args *);
+int linux_newfstatat(struct thread *, struct linux_newfstatat_args *);
+int linux_unlinkat(struct thread *, struct linux_unlinkat_args *);
+int linux_renameat(struct thread *, struct linux_renameat_args *);
+int linux_linkat(struct thread *, struct linux_linkat_args *);
+int linux_symlinkat(struct thread *, struct linux_symlinkat_args *);
+int linux_readlinkat(struct thread *, struct linux_readlinkat_args *);
+int linux_fchmodat(struct thread *, struct linux_fchmodat_args *);
+int linux_faccessat(struct thread *, struct linux_faccessat_args *);
+int linux_pselect6(struct thread *, struct linux_pselect6_args *);
+int linux_ppoll(struct thread *, struct linux_ppoll_args *);
+int linux_unshare(struct thread *, struct linux_unshare_args *);
+int linux_set_robust_list(struct thread *, struct linux_set_robust_list_args *);
+int linux_get_robust_list(struct thread *, struct linux_get_robust_list_args *);
+int linux_splice(struct thread *, struct linux_splice_args *);
+int linux_tee(struct thread *, struct linux_tee_args *);
+int linux_sync_file_range(struct thread *, struct linux_sync_file_range_args *);
+int linux_vmsplice(struct thread *, struct linux_vmsplice_args *);
+int linux_move_pages(struct thread *, struct linux_move_pages_args *);
+int linux_utimensat(struct thread *, struct linux_utimensat_args *);
+int linux_epoll_pwait(struct thread *, struct linux_epoll_pwait_args *);
+int linux_signalfd(struct thread *, struct linux_signalfd_args *);
+int linux_timerfd(struct thread *, struct linux_timerfd_args *);
+int linux_eventfd(struct thread *, struct linux_eventfd_args *);
+int linux_fallocate(struct thread *, struct linux_fallocate_args *);
+int linux_timerfd_settime(struct thread *, struct linux_timerfd_settime_args *);
+int linux_timerfd_gettime(struct thread *, struct linux_timerfd_gettime_args *);
+int linux_accept4(struct thread *, struct linux_accept4_args *);
+int linux_signalfd4(struct thread *, struct linux_signalfd4_args *);
+int linux_eventfd2(struct thread *, struct linux_eventfd2_args *);
+int linux_epoll_create1(struct thread *, struct linux_epoll_create1_args *);
+int linux_dup3(struct thread *, struct linux_dup3_args *);
+int linux_pipe2(struct thread *, struct linux_pipe2_args *);
+int linux_inotify_init1(struct thread *, struct linux_inotify_init1_args *);
+int linux_preadv(struct thread *, struct linux_preadv_args *);
+int linux_pwritev(struct thread *, struct linux_pwritev_args *);
+int linux_rt_tsigqueueinfo(struct thread *, struct linux_rt_tsigqueueinfo_args *);
+int linux_perf_event_open(struct thread *, struct linux_perf_event_open_args *);
+int linux_recvmmsg(struct thread *, struct linux_recvmmsg_args *);
+int linux_fanotify_init(struct thread *, struct linux_fanotify_init_args *);
+int linux_fanotify_mark(struct thread *, struct linux_fanotify_mark_args *);
+int linux_prlimit64(struct thread *, struct linux_prlimit64_args *);
+int linux_name_to_handle_at(struct thread *, struct linux_name_to_handle_at_args *);
+int linux_open_by_handle_at(struct thread *, struct linux_open_by_handle_at_args *);
+int linux_clock_adjtime(struct thread *, struct linux_clock_adjtime_args *);
+int linux_syncfs(struct thread *, struct linux_syncfs_args *);
+int linux_sendmmsg(struct thread *, struct linux_sendmmsg_args *);
+int linux_setns(struct thread *, struct linux_setns_args *);
+int linux_process_vm_readv(struct thread *, struct linux_process_vm_readv_args *);
+int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args *);
+int linux_kcmp(struct thread *, struct linux_kcmp_args *);
+int linux_finit_module(struct thread *, struct linux_finit_module_args *);
+
+#ifdef COMPAT_43
+
+#define nosys linux_nosys
+
+#endif /* COMPAT_43 */
+
+
+#ifdef COMPAT_FREEBSD4
+
+#define nosys linux_nosys
+
+#endif /* COMPAT_FREEBSD4 */
+
+
+#ifdef COMPAT_FREEBSD6
+
+#define nosys linux_nosys
+
+#endif /* COMPAT_FREEBSD6 */
+
+
+#ifdef COMPAT_FREEBSD7
+
+#define nosys linux_nosys
+
+#endif /* COMPAT_FREEBSD7 */
+
+#define LINUX_SYS_AUE_linux_open AUE_OPEN_RWTC
+#define LINUX_SYS_AUE_linux_newstat AUE_STAT
+#define LINUX_SYS_AUE_linux_newfstat AUE_FSTAT
+#define LINUX_SYS_AUE_linux_newlstat AUE_LSTAT
+#define LINUX_SYS_AUE_linux_lseek AUE_LSEEK
+#define LINUX_SYS_AUE_linux_mmap2 AUE_MMAP
+#define LINUX_SYS_AUE_linux_mprotect AUE_MPROTECT
+#define LINUX_SYS_AUE_linux_brk AUE_NULL
+#define LINUX_SYS_AUE_linux_rt_sigaction AUE_NULL
+#define LINUX_SYS_AUE_linux_rt_sigprocmask AUE_NULL
+#define LINUX_SYS_AUE_linux_rt_sigreturn AUE_NULL
+#define LINUX_SYS_AUE_linux_ioctl AUE_IOCTL
+#define LINUX_SYS_AUE_linux_pread AUE_PREAD
+#define LINUX_SYS_AUE_linux_pwrite AUE_PWRITE
+#define LINUX_SYS_AUE_linux_access AUE_ACCESS
+#define LINUX_SYS_AUE_linux_pipe AUE_PIPE
+#define LINUX_SYS_AUE_linux_select AUE_SELECT
+#define LINUX_SYS_AUE_linux_mremap AUE_NULL
+#define LINUX_SYS_AUE_linux_msync AUE_MSYNC
+#define LINUX_SYS_AUE_linux_mincore AUE_MINCORE
+#define LINUX_SYS_AUE_linux_shmget AUE_NULL
+#define LINUX_SYS_AUE_linux_shmat AUE_NULL
+#define LINUX_SYS_AUE_linux_shmctl AUE_NULL
+#define LINUX_SYS_AUE_linux_pause AUE_NULL
+#define LINUX_SYS_AUE_linux_nanosleep AUE_NULL
+#define LINUX_SYS_AUE_linux_getitimer AUE_GETITIMER
+#define LINUX_SYS_AUE_linux_alarm AUE_NULL
+#define LINUX_SYS_AUE_linux_setitimer AUE_SETITIMER
+#define LINUX_SYS_AUE_linux_getpid AUE_GETPID
+#define LINUX_SYS_AUE_linux_sendfile AUE_SENDFILE
+#define LINUX_SYS_AUE_linux_socket AUE_SOCKET
+#define LINUX_SYS_AUE_linux_connect AUE_CONNECT
+#define LINUX_SYS_AUE_linux_accept AUE_ACCEPT
+#define LINUX_SYS_AUE_linux_sendto AUE_SENDTO
+#define LINUX_SYS_AUE_linux_recvfrom AUE_RECVFROM
+#define LINUX_SYS_AUE_linux_sendmsg AUE_SENDMSG
+#define LINUX_SYS_AUE_linux_recvmsg AUE_RECVMSG
+#define LINUX_SYS_AUE_linux_shutdown AUE_NULL
+#define LINUX_SYS_AUE_linux_bind AUE_BIND
+#define LINUX_SYS_AUE_linux_listen AUE_LISTEN
+#define LINUX_SYS_AUE_linux_getsockname AUE_GETSOCKNAME
+#define LINUX_SYS_AUE_linux_getpeername AUE_GETPEERNAME
+#define LINUX_SYS_AUE_linux_socketpair AUE_SOCKETPAIR
+#define LINUX_SYS_AUE_linux_setsockopt AUE_SETSOCKOPT
+#define LINUX_SYS_AUE_linux_getsockopt AUE_GETSOCKOPT
+#define LINUX_SYS_AUE_linux_clone AUE_RFORK
+#define LINUX_SYS_AUE_linux_fork AUE_FORK
+#define LINUX_SYS_AUE_linux_vfork AUE_VFORK
+#define LINUX_SYS_AUE_linux_execve AUE_EXECVE
+#define LINUX_SYS_AUE_linux_exit AUE_EXIT
+#define LINUX_SYS_AUE_linux_wait4 AUE_WAIT4
+#define LINUX_SYS_AUE_linux_kill AUE_KILL
+#define LINUX_SYS_AUE_linux_newuname AUE_NULL
+#define LINUX_SYS_AUE_linux_semget AUE_NULL
+#define LINUX_SYS_AUE_linux_semop AUE_NULL
+#define LINUX_SYS_AUE_linux_semctl AUE_NULL
+#define LINUX_SYS_AUE_linux_shmdt AUE_NULL
+#define LINUX_SYS_AUE_linux_msgget AUE_NULL
+#define LINUX_SYS_AUE_linux_msgsnd AUE_NULL
+#define LINUX_SYS_AUE_linux_msgrcv AUE_NULL
+#define LINUX_SYS_AUE_linux_msgctl AUE_NULL
+#define LINUX_SYS_AUE_linux_fcntl AUE_FCNTL
+#define LINUX_SYS_AUE_linux_fdatasync AUE_NULL
+#define LINUX_SYS_AUE_linux_truncate AUE_TRUNCATE
+#define LINUX_SYS_AUE_linux_ftruncate AUE_FTRUNCATE
+#define LINUX_SYS_AUE_linux_getdents AUE_GETDIRENTRIES
+#define LINUX_SYS_AUE_linux_getcwd AUE_GETCWD
+#define LINUX_SYS_AUE_linux_chdir AUE_CHDIR
+#define LINUX_SYS_AUE_linux_rename AUE_RENAME
+#define LINUX_SYS_AUE_linux_mkdir AUE_MKDIR
+#define LINUX_SYS_AUE_linux_rmdir AUE_RMDIR
+#define LINUX_SYS_AUE_linux_creat AUE_CREAT
+#define LINUX_SYS_AUE_linux_link AUE_LINK
+#define LINUX_SYS_AUE_linux_unlink AUE_UNLINK
+#define LINUX_SYS_AUE_linux_symlink AUE_SYMLINK
+#define LINUX_SYS_AUE_linux_readlink AUE_READLINK
+#define LINUX_SYS_AUE_linux_chmod AUE_CHMOD
+#define LINUX_SYS_AUE_linux_chown AUE_LCHOWN
+#define LINUX_SYS_AUE_linux_lchown AUE_LCHOWN
+#define LINUX_SYS_AUE_linux_getrlimit AUE_GETRLIMIT
+#define LINUX_SYS_AUE_linux_sysinfo AUE_NULL
+#define LINUX_SYS_AUE_linux_times AUE_NULL
+#define LINUX_SYS_AUE_linux_ptrace AUE_PTRACE
+#define LINUX_SYS_AUE_linux_getuid AUE_GETUID
+#define LINUX_SYS_AUE_linux_syslog AUE_NULL
+#define LINUX_SYS_AUE_linux_getgid AUE_GETGID
+#define LINUX_SYS_AUE_linux_getppid AUE_GETPPID
+#define LINUX_SYS_AUE_linux_getgroups AUE_GETGROUPS
+#define LINUX_SYS_AUE_linux_setgroups AUE_SETGROUPS
+#define LINUX_SYS_AUE_linux_setfsuid AUE_SETFSUID
+#define LINUX_SYS_AUE_linux_setfsgid AUE_SETFSGID
+#define LINUX_SYS_AUE_linux_getsid AUE_GETSID
+#define LINUX_SYS_AUE_linux_capget AUE_CAPGET
+#define LINUX_SYS_AUE_linux_capset AUE_CAPSET
+#define LINUX_SYS_AUE_linux_rt_sigpending AUE_NULL
+#define LINUX_SYS_AUE_linux_rt_sigtimedwait AUE_NULL
+#define LINUX_SYS_AUE_linux_rt_sigqueueinfo AUE_NULL
+#define LINUX_SYS_AUE_linux_rt_sigsuspend AUE_NULL
+#define LINUX_SYS_AUE_linux_sigaltstack AUE_NULL
+#define LINUX_SYS_AUE_linux_utime AUE_UTIME
+#define LINUX_SYS_AUE_linux_mknod AUE_MKNOD
+#define LINUX_SYS_AUE_linux_personality AUE_PERSONALITY
+#define LINUX_SYS_AUE_linux_ustat AUE_NULL
+#define LINUX_SYS_AUE_linux_statfs AUE_STATFS
+#define LINUX_SYS_AUE_linux_fstatfs AUE_FSTATFS
+#define LINUX_SYS_AUE_linux_sysfs AUE_NULL
+#define LINUX_SYS_AUE_linux_getpriority AUE_GETPRIORITY
+#define LINUX_SYS_AUE_linux_sched_setparam AUE_SCHED_SETPARAM
+#define LINUX_SYS_AUE_linux_sched_getparam AUE_SCHED_GETPARAM
+#define LINUX_SYS_AUE_linux_sched_setscheduler AUE_SCHED_SETSCHEDULER
+#define LINUX_SYS_AUE_linux_sched_getscheduler AUE_SCHED_GETSCHEDULER
+#define LINUX_SYS_AUE_linux_sched_get_priority_max AUE_SCHED_GET_PRIORITY_MAX
+#define LINUX_SYS_AUE_linux_sched_get_priority_min AUE_SCHED_GET_PRIORITY_MIN
+#define LINUX_SYS_AUE_linux_sched_rr_get_interval AUE_SCHED_RR_GET_INTERVAL
+#define LINUX_SYS_AUE_linux_vhangup AUE_NULL
+#define LINUX_SYS_AUE_linux_pivot_root AUE_PIVOT_ROOT
+#define LINUX_SYS_AUE_linux_sysctl AUE_SYSCTL
+#define LINUX_SYS_AUE_linux_prctl AUE_PRCTL
+#define LINUX_SYS_AUE_linux_arch_prctl AUE_PRCTL
+#define LINUX_SYS_AUE_linux_adjtimex AUE_ADJTIME
+#define LINUX_SYS_AUE_linux_setrlimit AUE_SETRLIMIT
+#define LINUX_SYS_AUE_linux_mount AUE_MOUNT
+#define LINUX_SYS_AUE_linux_umount AUE_UMOUNT
+#define LINUX_SYS_AUE_linux_swapoff AUE_SWAPOFF
+#define LINUX_SYS_AUE_linux_reboot AUE_REBOOT
+#define LINUX_SYS_AUE_linux_sethostname AUE_SYSCTL
+#define LINUX_SYS_AUE_linux_setdomainname AUE_SYSCTL
+#define LINUX_SYS_AUE_linux_iopl AUE_NULL
+#define LINUX_SYS_AUE_linux_create_module AUE_NULL
+#define LINUX_SYS_AUE_linux_init_module AUE_NULL
+#define LINUX_SYS_AUE_linux_delete_module AUE_NULL
+#define LINUX_SYS_AUE_linux_get_kernel_syms AUE_NULL
+#define LINUX_SYS_AUE_linux_query_module AUE_NULL
+#define LINUX_SYS_AUE_linux_quotactl AUE_QUOTACTL
+#define LINUX_SYS_AUE_linux_nfsservctl AUE_NULL
+#define LINUX_SYS_AUE_linux_getpmsg AUE_GETPMSG
+#define LINUX_SYS_AUE_linux_putpmsg AUE_PUTPMSG
+#define LINUX_SYS_AUE_linux_afs_syscall AUE_NULL
+#define LINUX_SYS_AUE_linux_tuxcall AUE_NULL
+#define LINUX_SYS_AUE_linux_security AUE_NULL
+#define LINUX_SYS_AUE_linux_gettid AUE_NULL
+#define LINUX_SYS_AUE_linux_setxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_lsetxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_fsetxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_getxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_lgetxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_fgetxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_listxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_llistxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_flistxattr AUE_NULL
+#define LINUX_SYS_AUE_linux_removexattr AUE_NULL
+#define LINUX_SYS_AUE_linux_lremovexattr AUE_NULL
+#define LINUX_SYS_AUE_linux_fremovexattr AUE_NULL
+#define LINUX_SYS_AUE_linux_tkill AUE_NULL
+#define LINUX_SYS_AUE_linux_time AUE_NULL
+#define LINUX_SYS_AUE_linux_sys_futex AUE_NULL
+#define LINUX_SYS_AUE_linux_sched_setaffinity AUE_NULL
+#define LINUX_SYS_AUE_linux_sched_getaffinity AUE_NULL
+#define LINUX_SYS_AUE_linux_set_thread_area AUE_NULL
+#define LINUX_SYS_AUE_linux_lookup_dcookie AUE_NULL
+#define LINUX_SYS_AUE_linux_epoll_create AUE_NULL
+#define LINUX_SYS_AUE_linux_epoll_ctl_old AUE_NULL
+#define LINUX_SYS_AUE_linux_epoll_wait_old AUE_NULL
+#define LINUX_SYS_AUE_linux_remap_file_pages AUE_NULL
+#define LINUX_SYS_AUE_linux_getdents64 AUE_GETDIRENTRIES
+#define LINUX_SYS_AUE_linux_set_tid_address AUE_NULL
+#define LINUX_SYS_AUE_linux_semtimedop AUE_NULL
+#define LINUX_SYS_AUE_linux_fadvise64 AUE_NULL
+#define LINUX_SYS_AUE_linux_timer_create AUE_NULL
+#define LINUX_SYS_AUE_linux_timer_settime AUE_NULL
+#define LINUX_SYS_AUE_linux_timer_gettime AUE_NULL
+#define LINUX_SYS_AUE_linux_timer_getoverrun AUE_NULL
+#define LINUX_SYS_AUE_linux_timer_delete AUE_NULL
+#define LINUX_SYS_AUE_linux_clock_settime AUE_CLOCK_SETTIME
+#define LINUX_SYS_AUE_linux_clock_gettime AUE_NULL
+#define LINUX_SYS_AUE_linux_clock_getres AUE_NULL
+#define LINUX_SYS_AUE_linux_clock_nanosleep AUE_NULL
+#define LINUX_SYS_AUE_linux_exit_group AUE_EXIT
+#define LINUX_SYS_AUE_linux_epoll_wait AUE_NULL
+#define LINUX_SYS_AUE_linux_epoll_ctl AUE_NULL
+#define LINUX_SYS_AUE_linux_tgkill AUE_NULL
+#define LINUX_SYS_AUE_linux_utimes AUE_UTIMES
+#define LINUX_SYS_AUE_linux_mbind AUE_NULL
+#define LINUX_SYS_AUE_linux_set_mempolicy AUE_NULL
+#define LINUX_SYS_AUE_linux_get_mempolicy AUE_NULL
+#define LINUX_SYS_AUE_linux_mq_open AUE_NULL
+#define LINUX_SYS_AUE_linux_mq_unlink AUE_NULL
+#define LINUX_SYS_AUE_linux_mq_timedsend AUE_NULL
+#define LINUX_SYS_AUE_linux_mq_timedreceive AUE_NULL
+#define LINUX_SYS_AUE_linux_mq_notify AUE_NULL
+#define LINUX_SYS_AUE_linux_mq_getsetattr AUE_NULL
+#define LINUX_SYS_AUE_linux_kexec_load AUE_NULL
+#define LINUX_SYS_AUE_linux_waitid AUE_WAIT6
+#define LINUX_SYS_AUE_linux_add_key AUE_NULL
+#define LINUX_SYS_AUE_linux_request_key AUE_NULL
+#define LINUX_SYS_AUE_linux_keyctl AUE_NULL
+#define LINUX_SYS_AUE_linux_ioprio_set AUE_NULL
+#define LINUX_SYS_AUE_linux_ioprio_get AUE_NULL
+#define LINUX_SYS_AUE_linux_inotify_init AUE_NULL
+#define LINUX_SYS_AUE_linux_inotify_add_watch AUE_NULL
+#define LINUX_SYS_AUE_linux_inotify_rm_watch AUE_NULL
+#define LINUX_SYS_AUE_linux_migrate_pages AUE_NULL
+#define LINUX_SYS_AUE_linux_openat AUE_OPEN_RWTC
+#define LINUX_SYS_AUE_linux_mkdirat AUE_MKDIRAT
+#define LINUX_SYS_AUE_linux_mknodat AUE_MKNODAT
+#define LINUX_SYS_AUE_linux_fchownat AUE_FCHOWNAT
+#define LINUX_SYS_AUE_linux_futimesat AUE_FUTIMESAT
+#define LINUX_SYS_AUE_linux_newfstatat AUE_FSTATAT
+#define LINUX_SYS_AUE_linux_unlinkat AUE_UNLINKAT
+#define LINUX_SYS_AUE_linux_renameat AUE_RENAMEAT
+#define LINUX_SYS_AUE_linux_linkat AUE_LINKAT
+#define LINUX_SYS_AUE_linux_symlinkat AUE_SYMLINKAT
+#define LINUX_SYS_AUE_linux_readlinkat AUE_READLINKAT
+#define LINUX_SYS_AUE_linux_fchmodat AUE_FCHMODAT
+#define LINUX_SYS_AUE_linux_faccessat AUE_FACCESSAT
+#define LINUX_SYS_AUE_linux_pselect6 AUE_SELECT
+#define LINUX_SYS_AUE_linux_ppoll AUE_POLL
+#define LINUX_SYS_AUE_linux_unshare AUE_NULL
+#define LINUX_SYS_AUE_linux_set_robust_list AUE_NULL
+#define LINUX_SYS_AUE_linux_get_robust_list AUE_NULL
+#define LINUX_SYS_AUE_linux_splice AUE_NULL
+#define LINUX_SYS_AUE_linux_tee AUE_NULL
+#define LINUX_SYS_AUE_linux_sync_file_range AUE_NULL
+#define LINUX_SYS_AUE_linux_vmsplice AUE_NULL
+#define LINUX_SYS_AUE_linux_move_pages AUE_NULL
+#define LINUX_SYS_AUE_linux_utimensat AUE_FUTIMESAT
+#define LINUX_SYS_AUE_linux_epoll_pwait AUE_NULL
+#define LINUX_SYS_AUE_linux_signalfd AUE_NULL
+#define LINUX_SYS_AUE_linux_timerfd AUE_NULL
+#define LINUX_SYS_AUE_linux_eventfd AUE_NULL
+#define LINUX_SYS_AUE_linux_fallocate AUE_NULL
+#define LINUX_SYS_AUE_linux_timerfd_settime AUE_NULL
+#define LINUX_SYS_AUE_linux_timerfd_gettime AUE_NULL
+#define LINUX_SYS_AUE_linux_accept4 AUE_ACCEPT
+#define LINUX_SYS_AUE_linux_signalfd4 AUE_NULL
+#define LINUX_SYS_AUE_linux_eventfd2 AUE_NULL
+#define LINUX_SYS_AUE_linux_epoll_create1 AUE_NULL
+#define LINUX_SYS_AUE_linux_dup3 AUE_NULL
+#define LINUX_SYS_AUE_linux_pipe2 AUE_NULL
+#define LINUX_SYS_AUE_linux_inotify_init1 AUE_NULL
+#define LINUX_SYS_AUE_linux_preadv AUE_NULL
+#define LINUX_SYS_AUE_linux_pwritev AUE_NULL
+#define LINUX_SYS_AUE_linux_rt_tsigqueueinfo AUE_NULL
+#define LINUX_SYS_AUE_linux_perf_event_open AUE_NULL
+#define LINUX_SYS_AUE_linux_recvmmsg AUE_NULL
+#define LINUX_SYS_AUE_linux_fanotify_init AUE_NULL
+#define LINUX_SYS_AUE_linux_fanotify_mark AUE_NULL
+#define LINUX_SYS_AUE_linux_prlimit64 AUE_NULL
+#define LINUX_SYS_AUE_linux_name_to_handle_at AUE_NULL
+#define LINUX_SYS_AUE_linux_open_by_handle_at AUE_NULL
+#define LINUX_SYS_AUE_linux_clock_adjtime AUE_NULL
+#define LINUX_SYS_AUE_linux_syncfs AUE_SYNC
+#define LINUX_SYS_AUE_linux_sendmmsg AUE_NULL
+#define LINUX_SYS_AUE_linux_setns AUE_NULL
+#define LINUX_SYS_AUE_linux_process_vm_readv AUE_NULL
+#define LINUX_SYS_AUE_linux_process_vm_writev AUE_NULL
+#define LINUX_SYS_AUE_linux_kcmp AUE_NULL
+#define LINUX_SYS_AUE_linux_finit_module AUE_NULL
+
+#undef PAD_
+#undef PADL_
+#undef PADR_
+
+#endif /* !_LINUX_SYSPROTO_H_ */
diff --git a/sys/amd64/linux/linux_support.s b/sys/amd64/linux/linux_support.s
new file mode 100644
index 000000000000..2a3ba1a47f11
--- /dev/null
+++ b/sys/amd64/linux/linux_support.s
@@ -0,0 +1,124 @@
+/*-
+ * Copyright (c) 2007 Konstantin Belousov
+ * 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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$
+ */
+
+#include "linux_assym.h" /* system definitions */
+#include <machine/asmacros.h> /* miscellaneous asm macros */
+
+#include "assym.s"
+
+futex_fault:
+ movq $0,PCB_ONFAULT(%r8)
+ movl $-EFAULT,%eax
+ ret
+
+ENTRY(futex_xchgl)
+ movq PCPU(CURPCB),%r8
+ movq $futex_fault,PCB_ONFAULT(%r8)
+ movq $VM_MAXUSER_ADDRESS-4,%rax
+ cmpq %rax,%rsi
+ ja futex_fault
+ xchgl %edi,(%rsi)
+ movl %edi,(%rdx)
+ xorl %eax,%eax
+ movq %rax,PCB_ONFAULT(%r8)
+ ret
+
+ENTRY(futex_addl)
+ movq PCPU(CURPCB),%r8
+ movq $futex_fault,PCB_ONFAULT(%r8)
+ movq $VM_MAXUSER_ADDRESS-4,%rax
+ cmpq %rax,%rsi
+ ja futex_fault
+#ifdef SMP
+ lock
+#endif
+ xaddl %edi,(%rsi)
+ movl %edi,(%rdx)
+ xorl %eax,%eax
+ movq %rax,PCB_ONFAULT(%r8)
+ ret
+
+ENTRY(futex_orl)
+ movq PCPU(CURPCB),%r8
+ movq $futex_fault,PCB_ONFAULT(%r8)
+ movq $VM_MAXUSER_ADDRESS-4,%rax
+ cmpq %rax,%rsi
+ ja futex_fault
+ movl (%rsi),%eax
+1: movl %eax,%ecx
+ orl %edi,%ecx
+#ifdef SMP
+ lock
+#endif
+ cmpxchgl %ecx,(%rsi)
+ jnz 1b
+ movl %eax,(%rdx)
+ xorl %eax,%eax
+ movq %rax,PCB_ONFAULT(%r8)
+ ret
+
+ENTRY(futex_andl)
+ movq PCPU(CURPCB),%r8
+ movq $futex_fault,PCB_ONFAULT(%r8)
+ movq $VM_MAXUSER_ADDRESS-4,%rax
+ cmpq %rax,%rsi
+ ja futex_fault
+ movl (%rsi),%eax
+1: movl %eax,%ecx
+ andl %edi,%ecx
+#ifdef SMP
+ lock
+#endif
+ cmpxchgl %ecx,(%rsi)
+ jnz 1b
+ movl %eax,(%rdx)
+ xorl %eax,%eax
+ movq %rax,PCB_ONFAULT(%r8)
+ ret
+
+ENTRY(futex_xorl)
+ movq PCPU(CURPCB),%r8
+ movq $futex_fault,PCB_ONFAULT(%r8)
+ movq $VM_MAXUSER_ADDRESS-4,%rax
+ cmpq %rax,%rsi
+ ja futex_fault
+ movl (%rsi),%eax
+1: movl %eax,%ecx
+ xorl %edi,%ecx
+#ifdef SMP
+ lock
+#endif
+ cmpxchgl %ecx,(%rsi)
+ jnz 1b
+ movl %eax,(%rdx)
+ xorl %eax,%eax
+ movq %rax,PCB_ONFAULT(%r8)
+ ret
diff --git a/sys/amd64/linux/linux_syscall.h b/sys/amd64/linux/linux_syscall.h
new file mode 100644
index 000000000000..19a02657d23b
--- /dev/null
+++ b/sys/amd64/linux/linux_syscall.h
@@ -0,0 +1,310 @@
+/*
+ * System call numbers.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * $FreeBSD$
+ * created from FreeBSD: head/sys/amd64/linux/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
+ */
+
+#define LINUX_SYS_read 0
+#define LINUX_SYS_write 1
+#define LINUX_SYS_linux_open 2
+#define LINUX_SYS_close 3
+#define LINUX_SYS_linux_newstat 4
+#define LINUX_SYS_linux_newfstat 5
+#define LINUX_SYS_linux_newlstat 6
+#define LINUX_SYS_poll 7
+#define LINUX_SYS_linux_lseek 8
+#define LINUX_SYS_linux_mmap2 9
+#define LINUX_SYS_linux_mprotect 10
+#define LINUX_SYS_munmap 11
+#define LINUX_SYS_linux_brk 12
+#define LINUX_SYS_linux_rt_sigaction 13
+#define LINUX_SYS_linux_rt_sigprocmask 14
+#define LINUX_SYS_linux_rt_sigreturn 15
+#define LINUX_SYS_linux_ioctl 16
+#define LINUX_SYS_linux_pread 17
+#define LINUX_SYS_linux_pwrite 18
+#define LINUX_SYS_readv 19
+#define LINUX_SYS_writev 20
+#define LINUX_SYS_linux_access 21
+#define LINUX_SYS_linux_pipe 22
+#define LINUX_SYS_linux_select 23
+#define LINUX_SYS_sched_yield 24
+#define LINUX_SYS_linux_mremap 25
+#define LINUX_SYS_linux_msync 26
+#define LINUX_SYS_linux_mincore 27
+#define LINUX_SYS_madvise 28
+#define LINUX_SYS_linux_shmget 29
+#define LINUX_SYS_linux_shmat 30
+#define LINUX_SYS_linux_shmctl 31
+#define LINUX_SYS_dup 32
+#define LINUX_SYS_dup2 33
+#define LINUX_SYS_linux_pause 34
+#define LINUX_SYS_linux_nanosleep 35
+#define LINUX_SYS_linux_getitimer 36
+#define LINUX_SYS_linux_alarm 37
+#define LINUX_SYS_linux_setitimer 38
+#define LINUX_SYS_linux_getpid 39
+#define LINUX_SYS_linux_sendfile 40
+#define LINUX_SYS_linux_socket 41
+#define LINUX_SYS_linux_connect 42
+#define LINUX_SYS_linux_accept 43
+#define LINUX_SYS_linux_sendto 44
+#define LINUX_SYS_linux_recvfrom 45
+#define LINUX_SYS_linux_sendmsg 46
+#define LINUX_SYS_linux_recvmsg 47
+#define LINUX_SYS_linux_shutdown 48
+#define LINUX_SYS_linux_bind 49
+#define LINUX_SYS_linux_listen 50
+#define LINUX_SYS_linux_getsockname 51
+#define LINUX_SYS_linux_getpeername 52
+#define LINUX_SYS_linux_socketpair 53
+#define LINUX_SYS_linux_setsockopt 54
+#define LINUX_SYS_linux_getsockopt 55
+#define LINUX_SYS_linux_clone 56
+#define LINUX_SYS_linux_fork 57
+#define LINUX_SYS_linux_vfork 58
+#define LINUX_SYS_linux_execve 59
+#define LINUX_SYS_linux_exit 60
+#define LINUX_SYS_linux_wait4 61
+#define LINUX_SYS_linux_kill 62
+#define LINUX_SYS_linux_newuname 63
+#define LINUX_SYS_linux_semget 64
+#define LINUX_SYS_linux_semop 65
+#define LINUX_SYS_linux_semctl 66
+#define LINUX_SYS_linux_shmdt 67
+#define LINUX_SYS_linux_msgget 68
+#define LINUX_SYS_linux_msgsnd 69
+#define LINUX_SYS_linux_msgrcv 70
+#define LINUX_SYS_linux_msgctl 71
+#define LINUX_SYS_linux_fcntl 72
+#define LINUX_SYS_flock 73
+#define LINUX_SYS_fsync 74
+#define LINUX_SYS_linux_fdatasync 75
+#define LINUX_SYS_linux_truncate 76
+#define LINUX_SYS_linux_ftruncate 77
+#define LINUX_SYS_linux_getdents 78
+#define LINUX_SYS_linux_getcwd 79
+#define LINUX_SYS_linux_chdir 80
+#define LINUX_SYS_fchdir 81
+#define LINUX_SYS_linux_rename 82
+#define LINUX_SYS_linux_mkdir 83
+#define LINUX_SYS_linux_rmdir 84
+#define LINUX_SYS_linux_creat 85
+#define LINUX_SYS_linux_link 86
+#define LINUX_SYS_linux_unlink 87
+#define LINUX_SYS_linux_symlink 88
+#define LINUX_SYS_linux_readlink 89
+#define LINUX_SYS_linux_chmod 90
+#define LINUX_SYS_fchmod 91
+#define LINUX_SYS_linux_chown 92
+#define LINUX_SYS_fchown 93
+#define LINUX_SYS_linux_lchown 94
+#define LINUX_SYS_umask 95
+#define LINUX_SYS_gettimeofday 96
+#define LINUX_SYS_linux_getrlimit 97
+#define LINUX_SYS_getrusage 98
+#define LINUX_SYS_linux_sysinfo 99
+#define LINUX_SYS_linux_times 100
+#define LINUX_SYS_linux_ptrace 101
+#define LINUX_SYS_linux_getuid 102
+#define LINUX_SYS_linux_syslog 103
+#define LINUX_SYS_linux_getgid 104
+#define LINUX_SYS_setuid 105
+#define LINUX_SYS_setgid 106
+#define LINUX_SYS_geteuid 107
+#define LINUX_SYS_getegid 108
+#define LINUX_SYS_setpgid 109
+#define LINUX_SYS_linux_getppid 110
+#define LINUX_SYS_getpgrp 111
+#define LINUX_SYS_setsid 112
+#define LINUX_SYS_setreuid 113
+#define LINUX_SYS_setregid 114
+#define LINUX_SYS_linux_getgroups 115
+#define LINUX_SYS_linux_setgroups 116
+#define LINUX_SYS_setresuid 117
+#define LINUX_SYS_getresuid 118
+#define LINUX_SYS_setresgid 119
+#define LINUX_SYS_getresgid 120
+#define LINUX_SYS_getpgid 121
+#define LINUX_SYS_linux_setfsuid 122
+#define LINUX_SYS_linux_setfsgid 123
+#define LINUX_SYS_linux_getsid 124
+#define LINUX_SYS_linux_capget 125
+#define LINUX_SYS_linux_capset 126
+#define LINUX_SYS_linux_rt_sigpending 127
+#define LINUX_SYS_linux_rt_sigtimedwait 128
+#define LINUX_SYS_linux_rt_sigqueueinfo 129
+#define LINUX_SYS_linux_rt_sigsuspend 130
+#define LINUX_SYS_linux_sigaltstack 131
+#define LINUX_SYS_linux_utime 132
+#define LINUX_SYS_linux_mknod 133
+#define LINUX_SYS_linux_personality 135
+#define LINUX_SYS_linux_ustat 136
+#define LINUX_SYS_linux_statfs 137
+#define LINUX_SYS_linux_fstatfs 138
+#define LINUX_SYS_linux_sysfs 139
+#define LINUX_SYS_linux_getpriority 140
+#define LINUX_SYS_setpriority 141
+#define LINUX_SYS_linux_sched_setparam 142
+#define LINUX_SYS_linux_sched_getparam 143
+#define LINUX_SYS_linux_sched_setscheduler 144
+#define LINUX_SYS_linux_sched_getscheduler 145
+#define LINUX_SYS_linux_sched_get_priority_max 146
+#define LINUX_SYS_linux_sched_get_priority_min 147
+#define LINUX_SYS_linux_sched_rr_get_interval 148
+#define LINUX_SYS_mlock 149
+#define LINUX_SYS_munlock 150
+#define LINUX_SYS_mlockall 151
+#define LINUX_SYS_munlockall 152
+#define LINUX_SYS_linux_vhangup 153
+#define LINUX_SYS_linux_pivot_root 155
+#define LINUX_SYS_linux_sysctl 156
+#define LINUX_SYS_linux_prctl 157
+#define LINUX_SYS_linux_arch_prctl 158
+#define LINUX_SYS_linux_adjtimex 159
+#define LINUX_SYS_linux_setrlimit 160
+#define LINUX_SYS_chroot 161
+#define LINUX_SYS_sync 162
+#define LINUX_SYS_acct 163
+#define LINUX_SYS_settimeofday 164
+#define LINUX_SYS_linux_mount 165
+#define LINUX_SYS_linux_umount 166
+#define LINUX_SYS_swapon 167
+#define LINUX_SYS_linux_swapoff 168
+#define LINUX_SYS_linux_reboot 169
+#define LINUX_SYS_linux_sethostname 170
+#define LINUX_SYS_linux_setdomainname 171
+#define LINUX_SYS_linux_iopl 172
+#define LINUX_SYS_linux_create_module 174
+#define LINUX_SYS_linux_init_module 175
+#define LINUX_SYS_linux_delete_module 176
+#define LINUX_SYS_linux_get_kernel_syms 177
+#define LINUX_SYS_linux_query_module 178
+#define LINUX_SYS_linux_quotactl 179
+#define LINUX_SYS_linux_nfsservctl 180
+#define LINUX_SYS_linux_getpmsg 181
+#define LINUX_SYS_linux_putpmsg 182
+#define LINUX_SYS_linux_afs_syscall 183
+#define LINUX_SYS_linux_tuxcall 184
+#define LINUX_SYS_linux_security 185
+#define LINUX_SYS_linux_gettid 186
+#define LINUX_SYS_linux_setxattr 188
+#define LINUX_SYS_linux_lsetxattr 189
+#define LINUX_SYS_linux_fsetxattr 190
+#define LINUX_SYS_linux_getxattr 191
+#define LINUX_SYS_linux_lgetxattr 192
+#define LINUX_SYS_linux_fgetxattr 193
+#define LINUX_SYS_linux_listxattr 194
+#define LINUX_SYS_linux_llistxattr 195
+#define LINUX_SYS_linux_flistxattr 196
+#define LINUX_SYS_linux_removexattr 197
+#define LINUX_SYS_linux_lremovexattr 198
+#define LINUX_SYS_linux_fremovexattr 199
+#define LINUX_SYS_linux_tkill 200
+#define LINUX_SYS_linux_time 201
+#define LINUX_SYS_linux_sys_futex 202
+#define LINUX_SYS_linux_sched_setaffinity 203
+#define LINUX_SYS_linux_sched_getaffinity 204
+#define LINUX_SYS_linux_set_thread_area 205
+#define LINUX_SYS_linux_lookup_dcookie 212
+#define LINUX_SYS_linux_epoll_create 213
+#define LINUX_SYS_linux_epoll_ctl_old 214
+#define LINUX_SYS_linux_epoll_wait_old 215
+#define LINUX_SYS_linux_remap_file_pages 216
+#define LINUX_SYS_linux_getdents64 217
+#define LINUX_SYS_linux_set_tid_address 218
+#define LINUX_SYS_linux_semtimedop 220
+#define LINUX_SYS_linux_fadvise64 221
+#define LINUX_SYS_linux_timer_create 222
+#define LINUX_SYS_linux_timer_settime 223
+#define LINUX_SYS_linux_timer_gettime 224
+#define LINUX_SYS_linux_timer_getoverrun 225
+#define LINUX_SYS_linux_timer_delete 226
+#define LINUX_SYS_linux_clock_settime 227
+#define LINUX_SYS_linux_clock_gettime 228
+#define LINUX_SYS_linux_clock_getres 229
+#define LINUX_SYS_linux_clock_nanosleep 230
+#define LINUX_SYS_linux_exit_group 231
+#define LINUX_SYS_linux_epoll_wait 232
+#define LINUX_SYS_linux_epoll_ctl 233
+#define LINUX_SYS_linux_tgkill 234
+#define LINUX_SYS_linux_utimes 235
+#define LINUX_SYS_linux_mbind 237
+#define LINUX_SYS_linux_set_mempolicy 238
+#define LINUX_SYS_linux_get_mempolicy 239
+#define LINUX_SYS_linux_mq_open 240
+#define LINUX_SYS_linux_mq_unlink 241
+#define LINUX_SYS_linux_mq_timedsend 242
+#define LINUX_SYS_linux_mq_timedreceive 243
+#define LINUX_SYS_linux_mq_notify 244
+#define LINUX_SYS_linux_mq_getsetattr 245
+#define LINUX_SYS_linux_kexec_load 246
+#define LINUX_SYS_linux_waitid 247
+#define LINUX_SYS_linux_add_key 248
+#define LINUX_SYS_linux_request_key 249
+#define LINUX_SYS_linux_keyctl 250
+#define LINUX_SYS_linux_ioprio_set 251
+#define LINUX_SYS_linux_ioprio_get 252
+#define LINUX_SYS_linux_inotify_init 253
+#define LINUX_SYS_linux_inotify_add_watch 254
+#define LINUX_SYS_linux_inotify_rm_watch 255
+#define LINUX_SYS_linux_migrate_pages 256
+#define LINUX_SYS_linux_openat 257
+#define LINUX_SYS_linux_mkdirat 258
+#define LINUX_SYS_linux_mknodat 259
+#define LINUX_SYS_linux_fchownat 260
+#define LINUX_SYS_linux_futimesat 261
+#define LINUX_SYS_linux_newfstatat 262
+#define LINUX_SYS_linux_unlinkat 263
+#define LINUX_SYS_linux_renameat 264
+#define LINUX_SYS_linux_linkat 265
+#define LINUX_SYS_linux_symlinkat 266
+#define LINUX_SYS_linux_readlinkat 267
+#define LINUX_SYS_linux_fchmodat 268
+#define LINUX_SYS_linux_faccessat 269
+#define LINUX_SYS_linux_pselect6 270
+#define LINUX_SYS_linux_ppoll 271
+#define LINUX_SYS_linux_unshare 272
+#define LINUX_SYS_linux_set_robust_list 273
+#define LINUX_SYS_linux_get_robust_list 274
+#define LINUX_SYS_linux_splice 275
+#define LINUX_SYS_linux_tee 276
+#define LINUX_SYS_linux_sync_file_range 277
+#define LINUX_SYS_linux_vmsplice 278
+#define LINUX_SYS_linux_move_pages 279
+#define LINUX_SYS_linux_utimensat 280
+#define LINUX_SYS_linux_epoll_pwait 281
+#define LINUX_SYS_linux_signalfd 282
+#define LINUX_SYS_linux_timerfd 283
+#define LINUX_SYS_linux_eventfd 284
+#define LINUX_SYS_linux_fallocate 285
+#define LINUX_SYS_linux_timerfd_settime 286
+#define LINUX_SYS_linux_timerfd_gettime 287
+#define LINUX_SYS_linux_accept4 288
+#define LINUX_SYS_linux_signalfd4 289
+#define LINUX_SYS_linux_eventfd2 290
+#define LINUX_SYS_linux_epoll_create1 291
+#define LINUX_SYS_linux_dup3 292
+#define LINUX_SYS_linux_pipe2 293
+#define LINUX_SYS_linux_inotify_init1 294
+#define LINUX_SYS_linux_preadv 295
+#define LINUX_SYS_linux_pwritev 296
+#define LINUX_SYS_linux_rt_tsigqueueinfo 297
+#define LINUX_SYS_linux_perf_event_open 298
+#define LINUX_SYS_linux_recvmmsg 299
+#define LINUX_SYS_linux_fanotify_init 300
+#define LINUX_SYS_linux_fanotify_mark 301
+#define LINUX_SYS_linux_prlimit64 302
+#define LINUX_SYS_linux_name_to_handle_at 303
+#define LINUX_SYS_linux_open_by_handle_at 304
+#define LINUX_SYS_linux_clock_adjtime 305
+#define LINUX_SYS_linux_syncfs 306
+#define LINUX_SYS_linux_sendmmsg 307
+#define LINUX_SYS_linux_setns 308
+#define LINUX_SYS_linux_process_vm_readv 309
+#define LINUX_SYS_linux_process_vm_writev 310
+#define LINUX_SYS_linux_kcmp 311
+#define LINUX_SYS_linux_finit_module 312
+#define LINUX_SYS_MAXSYSCALL 314
diff --git a/sys/amd64/linux/linux_syscalls.c b/sys/amd64/linux/linux_syscalls.c
new file mode 100644
index 000000000000..f19d28546093
--- /dev/null
+++ b/sys/amd64/linux/linux_syscalls.c
@@ -0,0 +1,325 @@
+/*
+ * System call names.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * $FreeBSD$
+ * created from FreeBSD: head/sys/amd64/linux/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
+ */
+
+const char *linux_syscallnames[] = {
+#define nosys linux_nosys
+ "read", /* 0 = read */
+ "write", /* 1 = write */
+ "linux_open", /* 2 = linux_open */
+ "close", /* 3 = close */
+ "linux_newstat", /* 4 = linux_newstat */
+ "linux_newfstat", /* 5 = linux_newfstat */
+ "linux_newlstat", /* 6 = linux_newlstat */
+ "poll", /* 7 = poll */
+ "linux_lseek", /* 8 = linux_lseek */
+ "linux_mmap2", /* 9 = linux_mmap2 */
+ "linux_mprotect", /* 10 = linux_mprotect */
+ "munmap", /* 11 = munmap */
+ "linux_brk", /* 12 = linux_brk */
+ "linux_rt_sigaction", /* 13 = linux_rt_sigaction */
+ "linux_rt_sigprocmask", /* 14 = linux_rt_sigprocmask */
+ "linux_rt_sigreturn", /* 15 = linux_rt_sigreturn */
+ "linux_ioctl", /* 16 = linux_ioctl */
+ "linux_pread", /* 17 = linux_pread */
+ "linux_pwrite", /* 18 = linux_pwrite */
+ "readv", /* 19 = readv */
+ "writev", /* 20 = writev */
+ "linux_access", /* 21 = linux_access */
+ "linux_pipe", /* 22 = linux_pipe */
+ "linux_select", /* 23 = linux_select */
+ "sched_yield", /* 24 = sched_yield */
+ "linux_mremap", /* 25 = linux_mremap */
+ "linux_msync", /* 26 = linux_msync */
+ "linux_mincore", /* 27 = linux_mincore */
+ "madvise", /* 28 = madvise */
+ "linux_shmget", /* 29 = linux_shmget */
+ "linux_shmat", /* 30 = linux_shmat */
+ "linux_shmctl", /* 31 = linux_shmctl */
+ "dup", /* 32 = dup */
+ "dup2", /* 33 = dup2 */
+ "linux_pause", /* 34 = linux_pause */
+ "linux_nanosleep", /* 35 = linux_nanosleep */
+ "linux_getitimer", /* 36 = linux_getitimer */
+ "linux_alarm", /* 37 = linux_alarm */
+ "linux_setitimer", /* 38 = linux_setitimer */
+ "linux_getpid", /* 39 = linux_getpid */
+ "linux_sendfile", /* 40 = linux_sendfile */
+ "linux_socket", /* 41 = linux_socket */
+ "linux_connect", /* 42 = linux_connect */
+ "linux_accept", /* 43 = linux_accept */
+ "linux_sendto", /* 44 = linux_sendto */
+ "linux_recvfrom", /* 45 = linux_recvfrom */
+ "linux_sendmsg", /* 46 = linux_sendmsg */
+ "linux_recvmsg", /* 47 = linux_recvmsg */
+ "linux_shutdown", /* 48 = linux_shutdown */
+ "linux_bind", /* 49 = linux_bind */
+ "linux_listen", /* 50 = linux_listen */
+ "linux_getsockname", /* 51 = linux_getsockname */
+ "linux_getpeername", /* 52 = linux_getpeername */
+ "linux_socketpair", /* 53 = linux_socketpair */
+ "linux_setsockopt", /* 54 = linux_setsockopt */
+ "linux_getsockopt", /* 55 = linux_getsockopt */
+ "linux_clone", /* 56 = linux_clone */
+ "linux_fork", /* 57 = linux_fork */
+ "linux_vfork", /* 58 = linux_vfork */
+ "linux_execve", /* 59 = linux_execve */
+ "linux_exit", /* 60 = linux_exit */
+ "linux_wait4", /* 61 = linux_wait4 */
+ "linux_kill", /* 62 = linux_kill */
+ "linux_newuname", /* 63 = linux_newuname */
+ "linux_semget", /* 64 = linux_semget */
+ "linux_semop", /* 65 = linux_semop */
+ "linux_semctl", /* 66 = linux_semctl */
+ "linux_shmdt", /* 67 = linux_shmdt */
+ "linux_msgget", /* 68 = linux_msgget */
+ "linux_msgsnd", /* 69 = linux_msgsnd */
+ "linux_msgrcv", /* 70 = linux_msgrcv */
+ "linux_msgctl", /* 71 = linux_msgctl */
+ "linux_fcntl", /* 72 = linux_fcntl */
+ "flock", /* 73 = flock */
+ "fsync", /* 74 = fsync */
+ "linux_fdatasync", /* 75 = linux_fdatasync */
+ "linux_truncate", /* 76 = linux_truncate */
+ "linux_ftruncate", /* 77 = linux_ftruncate */
+ "linux_getdents", /* 78 = linux_getdents */
+ "linux_getcwd", /* 79 = linux_getcwd */
+ "linux_chdir", /* 80 = linux_chdir */
+ "fchdir", /* 81 = fchdir */
+ "linux_rename", /* 82 = linux_rename */
+ "linux_mkdir", /* 83 = linux_mkdir */
+ "linux_rmdir", /* 84 = linux_rmdir */
+ "linux_creat", /* 85 = linux_creat */
+ "linux_link", /* 86 = linux_link */
+ "linux_unlink", /* 87 = linux_unlink */
+ "linux_symlink", /* 88 = linux_symlink */
+ "linux_readlink", /* 89 = linux_readlink */
+ "linux_chmod", /* 90 = linux_chmod */
+ "fchmod", /* 91 = fchmod */
+ "linux_chown", /* 92 = linux_chown */
+ "fchown", /* 93 = fchown */
+ "linux_lchown", /* 94 = linux_lchown */
+ "umask", /* 95 = umask */
+ "gettimeofday", /* 96 = gettimeofday */
+ "linux_getrlimit", /* 97 = linux_getrlimit */
+ "getrusage", /* 98 = getrusage */
+ "linux_sysinfo", /* 99 = linux_sysinfo */
+ "linux_times", /* 100 = linux_times */
+ "linux_ptrace", /* 101 = linux_ptrace */
+ "linux_getuid", /* 102 = linux_getuid */
+ "linux_syslog", /* 103 = linux_syslog */
+ "linux_getgid", /* 104 = linux_getgid */
+ "setuid", /* 105 = setuid */
+ "setgid", /* 106 = setgid */
+ "geteuid", /* 107 = geteuid */
+ "getegid", /* 108 = getegid */
+ "setpgid", /* 109 = setpgid */
+ "linux_getppid", /* 110 = linux_getppid */
+ "getpgrp", /* 111 = getpgrp */
+ "setsid", /* 112 = setsid */
+ "setreuid", /* 113 = setreuid */
+ "setregid", /* 114 = setregid */
+ "linux_getgroups", /* 115 = linux_getgroups */
+ "linux_setgroups", /* 116 = linux_setgroups */
+ "setresuid", /* 117 = setresuid */
+ "getresuid", /* 118 = getresuid */
+ "setresgid", /* 119 = setresgid */
+ "getresgid", /* 120 = getresgid */
+ "getpgid", /* 121 = getpgid */
+ "linux_setfsuid", /* 122 = linux_setfsuid */
+ "linux_setfsgid", /* 123 = linux_setfsgid */
+ "linux_getsid", /* 124 = linux_getsid */
+ "linux_capget", /* 125 = linux_capget */
+ "linux_capset", /* 126 = linux_capset */
+ "linux_rt_sigpending", /* 127 = linux_rt_sigpending */
+ "linux_rt_sigtimedwait", /* 128 = linux_rt_sigtimedwait */
+ "linux_rt_sigqueueinfo", /* 129 = linux_rt_sigqueueinfo */
+ "linux_rt_sigsuspend", /* 130 = linux_rt_sigsuspend */
+ "linux_sigaltstack", /* 131 = linux_sigaltstack */
+ "linux_utime", /* 132 = linux_utime */
+ "linux_mknod", /* 133 = linux_mknod */
+ "#134", /* 134 = uselib */
+ "linux_personality", /* 135 = linux_personality */
+ "linux_ustat", /* 136 = linux_ustat */
+ "linux_statfs", /* 137 = linux_statfs */
+ "linux_fstatfs", /* 138 = linux_fstatfs */
+ "linux_sysfs", /* 139 = linux_sysfs */
+ "linux_getpriority", /* 140 = linux_getpriority */
+ "setpriority", /* 141 = setpriority */
+ "linux_sched_setparam", /* 142 = linux_sched_setparam */
+ "linux_sched_getparam", /* 143 = linux_sched_getparam */
+ "linux_sched_setscheduler", /* 144 = linux_sched_setscheduler */
+ "linux_sched_getscheduler", /* 145 = linux_sched_getscheduler */
+ "linux_sched_get_priority_max", /* 146 = linux_sched_get_priority_max */
+ "linux_sched_get_priority_min", /* 147 = linux_sched_get_priority_min */
+ "linux_sched_rr_get_interval", /* 148 = linux_sched_rr_get_interval */
+ "mlock", /* 149 = mlock */
+ "munlock", /* 150 = munlock */
+ "mlockall", /* 151 = mlockall */
+ "munlockall", /* 152 = munlockall */
+ "linux_vhangup", /* 153 = linux_vhangup */
+ "#154", /* 154 = modify_ldt */
+ "linux_pivot_root", /* 155 = linux_pivot_root */
+ "linux_sysctl", /* 156 = linux_sysctl */
+ "linux_prctl", /* 157 = linux_prctl */
+ "linux_arch_prctl", /* 158 = linux_arch_prctl */
+ "linux_adjtimex", /* 159 = linux_adjtimex */
+ "linux_setrlimit", /* 160 = linux_setrlimit */
+ "chroot", /* 161 = chroot */
+ "sync", /* 162 = sync */
+ "acct", /* 163 = acct */
+ "settimeofday", /* 164 = settimeofday */
+ "linux_mount", /* 165 = linux_mount */
+ "linux_umount", /* 166 = linux_umount */
+ "swapon", /* 167 = swapon */
+ "linux_swapoff", /* 168 = linux_swapoff */
+ "linux_reboot", /* 169 = linux_reboot */
+ "linux_sethostname", /* 170 = linux_sethostname */
+ "linux_setdomainname", /* 171 = linux_setdomainname */
+ "linux_iopl", /* 172 = linux_iopl */
+ "#173", /* 173 = ioperm */
+ "linux_create_module", /* 174 = linux_create_module */
+ "linux_init_module", /* 175 = linux_init_module */
+ "linux_delete_module", /* 176 = linux_delete_module */
+ "linux_get_kernel_syms", /* 177 = linux_get_kernel_syms */
+ "linux_query_module", /* 178 = linux_query_module */
+ "linux_quotactl", /* 179 = linux_quotactl */
+ "linux_nfsservctl", /* 180 = linux_nfsservctl */
+ "linux_getpmsg", /* 181 = linux_getpmsg */
+ "linux_putpmsg", /* 182 = linux_putpmsg */
+ "linux_afs_syscall", /* 183 = linux_afs_syscall */
+ "linux_tuxcall", /* 184 = linux_tuxcall */
+ "linux_security", /* 185 = linux_security */
+ "linux_gettid", /* 186 = linux_gettid */
+ "#187", /* 187 = linux_readahead */
+ "linux_setxattr", /* 188 = linux_setxattr */
+ "linux_lsetxattr", /* 189 = linux_lsetxattr */
+ "linux_fsetxattr", /* 190 = linux_fsetxattr */
+ "linux_getxattr", /* 191 = linux_getxattr */
+ "linux_lgetxattr", /* 192 = linux_lgetxattr */
+ "linux_fgetxattr", /* 193 = linux_fgetxattr */
+ "linux_listxattr", /* 194 = linux_listxattr */
+ "linux_llistxattr", /* 195 = linux_llistxattr */
+ "linux_flistxattr", /* 196 = linux_flistxattr */
+ "linux_removexattr", /* 197 = linux_removexattr */
+ "linux_lremovexattr", /* 198 = linux_lremovexattr */
+ "linux_fremovexattr", /* 199 = linux_fremovexattr */
+ "linux_tkill", /* 200 = linux_tkill */
+ "linux_time", /* 201 = linux_time */
+ "linux_sys_futex", /* 202 = linux_sys_futex */
+ "linux_sched_setaffinity", /* 203 = linux_sched_setaffinity */
+ "linux_sched_getaffinity", /* 204 = linux_sched_getaffinity */
+ "linux_set_thread_area", /* 205 = linux_set_thread_area */
+ "#206", /* 206 = linux_io_setup */
+ "#207", /* 207 = linux_io_destroy */
+ "#208", /* 208 = linux_io_getevents */
+ "#209", /* 209 = inux_io_submit */
+ "#210", /* 210 = linux_io_cancel */
+ "#211", /* 211 = linux_get_thread_area */
+ "linux_lookup_dcookie", /* 212 = linux_lookup_dcookie */
+ "linux_epoll_create", /* 213 = linux_epoll_create */
+ "linux_epoll_ctl_old", /* 214 = linux_epoll_ctl_old */
+ "linux_epoll_wait_old", /* 215 = linux_epoll_wait_old */
+ "linux_remap_file_pages", /* 216 = linux_remap_file_pages */
+ "linux_getdents64", /* 217 = linux_getdents64 */
+ "linux_set_tid_address", /* 218 = linux_set_tid_address */
+ "#219", /* 219 = restart_syscall */
+ "linux_semtimedop", /* 220 = linux_semtimedop */
+ "linux_fadvise64", /* 221 = linux_fadvise64 */
+ "linux_timer_create", /* 222 = linux_timer_create */
+ "linux_timer_settime", /* 223 = linux_timer_settime */
+ "linux_timer_gettime", /* 224 = linux_timer_gettime */
+ "linux_timer_getoverrun", /* 225 = linux_timer_getoverrun */
+ "linux_timer_delete", /* 226 = linux_timer_delete */
+ "linux_clock_settime", /* 227 = linux_clock_settime */
+ "linux_clock_gettime", /* 228 = linux_clock_gettime */
+ "linux_clock_getres", /* 229 = linux_clock_getres */
+ "linux_clock_nanosleep", /* 230 = linux_clock_nanosleep */
+ "linux_exit_group", /* 231 = linux_exit_group */
+ "linux_epoll_wait", /* 232 = linux_epoll_wait */
+ "linux_epoll_ctl", /* 233 = linux_epoll_ctl */
+ "linux_tgkill", /* 234 = linux_tgkill */
+ "linux_utimes", /* 235 = linux_utimes */
+ "#236", /* 236 = vserver */
+ "linux_mbind", /* 237 = linux_mbind */
+ "linux_set_mempolicy", /* 238 = linux_set_mempolicy */
+ "linux_get_mempolicy", /* 239 = linux_get_mempolicy */
+ "linux_mq_open", /* 240 = linux_mq_open */
+ "linux_mq_unlink", /* 241 = linux_mq_unlink */
+ "linux_mq_timedsend", /* 242 = linux_mq_timedsend */
+ "linux_mq_timedreceive", /* 243 = linux_mq_timedreceive */
+ "linux_mq_notify", /* 244 = linux_mq_notify */
+ "linux_mq_getsetattr", /* 245 = linux_mq_getsetattr */
+ "linux_kexec_load", /* 246 = linux_kexec_load */
+ "linux_waitid", /* 247 = linux_waitid */
+ "linux_add_key", /* 248 = linux_add_key */
+ "linux_request_key", /* 249 = linux_request_key */
+ "linux_keyctl", /* 250 = linux_keyctl */
+ "linux_ioprio_set", /* 251 = linux_ioprio_set */
+ "linux_ioprio_get", /* 252 = linux_ioprio_get */
+ "linux_inotify_init", /* 253 = linux_inotify_init */
+ "linux_inotify_add_watch", /* 254 = linux_inotify_add_watch */
+ "linux_inotify_rm_watch", /* 255 = linux_inotify_rm_watch */
+ "linux_migrate_pages", /* 256 = linux_migrate_pages */
+ "linux_openat", /* 257 = linux_openat */
+ "linux_mkdirat", /* 258 = linux_mkdirat */
+ "linux_mknodat", /* 259 = linux_mknodat */
+ "linux_fchownat", /* 260 = linux_fchownat */
+ "linux_futimesat", /* 261 = linux_futimesat */
+ "linux_newfstatat", /* 262 = linux_newfstatat */
+ "linux_unlinkat", /* 263 = linux_unlinkat */
+ "linux_renameat", /* 264 = linux_renameat */
+ "linux_linkat", /* 265 = linux_linkat */
+ "linux_symlinkat", /* 266 = linux_symlinkat */
+ "linux_readlinkat", /* 267 = linux_readlinkat */
+ "linux_fchmodat", /* 268 = linux_fchmodat */
+ "linux_faccessat", /* 269 = linux_faccessat */
+ "linux_pselect6", /* 270 = linux_pselect6 */
+ "linux_ppoll", /* 271 = linux_ppoll */
+ "linux_unshare", /* 272 = linux_unshare */
+ "linux_set_robust_list", /* 273 = linux_set_robust_list */
+ "linux_get_robust_list", /* 274 = linux_get_robust_list */
+ "linux_splice", /* 275 = linux_splice */
+ "linux_tee", /* 276 = linux_tee */
+ "linux_sync_file_range", /* 277 = linux_sync_file_range */
+ "linux_vmsplice", /* 278 = linux_vmsplice */
+ "linux_move_pages", /* 279 = linux_move_pages */
+ "linux_utimensat", /* 280 = linux_utimensat */
+ "linux_epoll_pwait", /* 281 = linux_epoll_pwait */
+ "linux_signalfd", /* 282 = linux_signalfd */
+ "linux_timerfd", /* 283 = linux_timerfd */
+ "linux_eventfd", /* 284 = linux_eventfd */
+ "linux_fallocate", /* 285 = linux_fallocate */
+ "linux_timerfd_settime", /* 286 = linux_timerfd_settime */
+ "linux_timerfd_gettime", /* 287 = linux_timerfd_gettime */
+ "linux_accept4", /* 288 = linux_accept4 */
+ "linux_signalfd4", /* 289 = linux_signalfd4 */
+ "linux_eventfd2", /* 290 = linux_eventfd2 */
+ "linux_epoll_create1", /* 291 = linux_epoll_create1 */
+ "linux_dup3", /* 292 = linux_dup3 */
+ "linux_pipe2", /* 293 = linux_pipe2 */
+ "linux_inotify_init1", /* 294 = linux_inotify_init1 */
+ "linux_preadv", /* 295 = linux_preadv */
+ "linux_pwritev", /* 296 = linux_pwritev */
+ "linux_rt_tsigqueueinfo", /* 297 = linux_rt_tsigqueueinfo */
+ "linux_perf_event_open", /* 298 = linux_perf_event_open */
+ "linux_recvmmsg", /* 299 = linux_recvmmsg */
+ "linux_fanotify_init", /* 300 = linux_fanotify_init */
+ "linux_fanotify_mark", /* 301 = linux_fanotify_mark */
+ "linux_prlimit64", /* 302 = linux_prlimit64 */
+ "linux_name_to_handle_at", /* 303 = linux_name_to_handle_at */
+ "linux_open_by_handle_at", /* 304 = linux_open_by_handle_at */
+ "linux_clock_adjtime", /* 305 = linux_clock_adjtime */
+ "linux_syncfs", /* 306 = linux_syncfs */
+ "linux_sendmmsg", /* 307 = linux_sendmmsg */
+ "linux_setns", /* 308 = linux_setns */
+ "linux_process_vm_readv", /* 309 = linux_process_vm_readv */
+ "linux_process_vm_writev", /* 310 = linux_process_vm_writev */
+ "linux_kcmp", /* 311 = linux_kcmp */
+ "linux_finit_module", /* 312 = linux_finit_module */
+ "#313", /* 313 = nosys */
+};
diff --git a/sys/amd64/linux/linux_sysent.c b/sys/amd64/linux/linux_sysent.c
new file mode 100644
index 000000000000..a575787a8a30
--- /dev/null
+++ b/sys/amd64/linux/linux_sysent.c
@@ -0,0 +1,335 @@
+/*
+ * System call switch table.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * $FreeBSD$
+ * created from FreeBSD: head/sys/amd64/linux/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
+ */
+
+#include <sys/param.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <compat/linux/linux_sysproto.h>
+#include <amd64/linux/linux.h>
+#include <amd64/linux/linux_proto.h>
+
+#define AS(name) (sizeof(struct name) / sizeof(register_t))
+
+/* The casts are bogus but will do for now. */
+struct sysent linux_sysent[] = {
+#define nosys linux_nosys
+ { AS(read_args), (sy_call_t *)sys_read, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 0 = read */
+ { AS(write_args), (sy_call_t *)sys_write, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = write */
+ { AS(linux_open_args), (sy_call_t *)linux_open, AUE_OPEN_RWTC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 2 = linux_open */
+ { AS(close_args), (sy_call_t *)sys_close, AUE_CLOSE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 3 = close */
+ { AS(linux_newstat_args), (sy_call_t *)linux_newstat, AUE_STAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 4 = linux_newstat */
+ { AS(linux_newfstat_args), (sy_call_t *)linux_newfstat, AUE_FSTAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 5 = linux_newfstat */
+ { AS(linux_newlstat_args), (sy_call_t *)linux_newlstat, AUE_LSTAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 6 = linux_newlstat */
+ { AS(poll_args), (sy_call_t *)sys_poll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 7 = poll */
+ { AS(linux_lseek_args), (sy_call_t *)linux_lseek, AUE_LSEEK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 8 = linux_lseek */
+ { AS(linux_mmap2_args), (sy_call_t *)linux_mmap2, AUE_MMAP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 9 = linux_mmap2 */
+ { AS(linux_mprotect_args), (sy_call_t *)linux_mprotect, AUE_MPROTECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 10 = linux_mprotect */
+ { AS(munmap_args), (sy_call_t *)sys_munmap, AUE_MUNMAP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 11 = munmap */
+ { AS(linux_brk_args), (sy_call_t *)linux_brk, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 12 = linux_brk */
+ { AS(linux_rt_sigaction_args), (sy_call_t *)linux_rt_sigaction, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 13 = linux_rt_sigaction */
+ { AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 14 = linux_rt_sigprocmask */
+ { AS(linux_rt_sigreturn_args), (sy_call_t *)linux_rt_sigreturn, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 15 = linux_rt_sigreturn */
+ { AS(linux_ioctl_args), (sy_call_t *)linux_ioctl, AUE_IOCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 16 = linux_ioctl */
+ { AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_PREAD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 17 = linux_pread */
+ { AS(linux_pwrite_args), (sy_call_t *)linux_pwrite, AUE_PWRITE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 18 = linux_pwrite */
+ { AS(readv_args), (sy_call_t *)sys_readv, AUE_READV, NULL, 0, 0, 0, SY_THR_STATIC }, /* 19 = readv */
+ { AS(writev_args), (sy_call_t *)sys_writev, AUE_WRITEV, NULL, 0, 0, 0, SY_THR_STATIC }, /* 20 = writev */
+ { AS(linux_access_args), (sy_call_t *)linux_access, AUE_ACCESS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 21 = linux_access */
+ { AS(linux_pipe_args), (sy_call_t *)linux_pipe, AUE_PIPE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 22 = linux_pipe */
+ { AS(linux_select_args), (sy_call_t *)linux_select, AUE_SELECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 23 = linux_select */
+ { 0, (sy_call_t *)sys_sched_yield, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 24 = sched_yield */
+ { AS(linux_mremap_args), (sy_call_t *)linux_mremap, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 25 = linux_mremap */
+ { AS(linux_msync_args), (sy_call_t *)linux_msync, AUE_MSYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 26 = linux_msync */
+ { AS(linux_mincore_args), (sy_call_t *)linux_mincore, AUE_MINCORE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 27 = linux_mincore */
+ { AS(madvise_args), (sy_call_t *)sys_madvise, AUE_MADVISE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 28 = madvise */
+ { AS(linux_shmget_args), (sy_call_t *)linux_shmget, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 29 = linux_shmget */
+ { AS(linux_shmat_args), (sy_call_t *)linux_shmat, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 30 = linux_shmat */
+ { AS(linux_shmctl_args), (sy_call_t *)linux_shmctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 31 = linux_shmctl */
+ { AS(dup_args), (sy_call_t *)sys_dup, AUE_DUP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 32 = dup */
+ { AS(dup2_args), (sy_call_t *)sys_dup2, AUE_DUP2, NULL, 0, 0, 0, SY_THR_STATIC }, /* 33 = dup2 */
+ { 0, (sy_call_t *)linux_pause, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 34 = linux_pause */
+ { AS(linux_nanosleep_args), (sy_call_t *)linux_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 35 = linux_nanosleep */
+ { AS(linux_getitimer_args), (sy_call_t *)linux_getitimer, AUE_GETITIMER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 36 = linux_getitimer */
+ { AS(linux_alarm_args), (sy_call_t *)linux_alarm, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 37 = linux_alarm */
+ { AS(linux_setitimer_args), (sy_call_t *)linux_setitimer, AUE_SETITIMER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 38 = linux_setitimer */
+ { 0, (sy_call_t *)linux_getpid, AUE_GETPID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 39 = linux_getpid */
+ { AS(linux_sendfile_args), (sy_call_t *)linux_sendfile, AUE_SENDFILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 40 = linux_sendfile */
+ { AS(linux_socket_args), (sy_call_t *)linux_socket, AUE_SOCKET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 41 = linux_socket */
+ { AS(linux_connect_args), (sy_call_t *)linux_connect, AUE_CONNECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 42 = linux_connect */
+ { AS(linux_accept_args), (sy_call_t *)linux_accept, AUE_ACCEPT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 43 = linux_accept */
+ { AS(linux_sendto_args), (sy_call_t *)linux_sendto, AUE_SENDTO, NULL, 0, 0, 0, SY_THR_STATIC }, /* 44 = linux_sendto */
+ { AS(linux_recvfrom_args), (sy_call_t *)linux_recvfrom, AUE_RECVFROM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 45 = linux_recvfrom */
+ { AS(linux_sendmsg_args), (sy_call_t *)linux_sendmsg, AUE_SENDMSG, NULL, 0, 0, 0, SY_THR_STATIC }, /* 46 = linux_sendmsg */
+ { AS(linux_recvmsg_args), (sy_call_t *)linux_recvmsg, AUE_RECVMSG, NULL, 0, 0, 0, SY_THR_STATIC }, /* 47 = linux_recvmsg */
+ { AS(linux_shutdown_args), (sy_call_t *)linux_shutdown, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 48 = linux_shutdown */
+ { AS(linux_bind_args), (sy_call_t *)linux_bind, AUE_BIND, NULL, 0, 0, 0, SY_THR_STATIC }, /* 49 = linux_bind */
+ { AS(linux_listen_args), (sy_call_t *)linux_listen, AUE_LISTEN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 50 = linux_listen */
+ { AS(linux_getsockname_args), (sy_call_t *)linux_getsockname, AUE_GETSOCKNAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 51 = linux_getsockname */
+ { AS(linux_getpeername_args), (sy_call_t *)linux_getpeername, AUE_GETPEERNAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 52 = linux_getpeername */
+ { AS(linux_socketpair_args), (sy_call_t *)linux_socketpair, AUE_SOCKETPAIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 53 = linux_socketpair */
+ { AS(linux_setsockopt_args), (sy_call_t *)linux_setsockopt, AUE_SETSOCKOPT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 54 = linux_setsockopt */
+ { AS(linux_getsockopt_args), (sy_call_t *)linux_getsockopt, AUE_GETSOCKOPT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 55 = linux_getsockopt */
+ { AS(linux_clone_args), (sy_call_t *)linux_clone, AUE_RFORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 56 = linux_clone */
+ { 0, (sy_call_t *)linux_fork, AUE_FORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 57 = linux_fork */
+ { 0, (sy_call_t *)linux_vfork, AUE_VFORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 58 = linux_vfork */
+ { AS(linux_execve_args), (sy_call_t *)linux_execve, AUE_EXECVE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 59 = linux_execve */
+ { AS(linux_exit_args), (sy_call_t *)linux_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 60 = linux_exit */
+ { AS(linux_wait4_args), (sy_call_t *)linux_wait4, AUE_WAIT4, NULL, 0, 0, 0, SY_THR_STATIC }, /* 61 = linux_wait4 */
+ { AS(linux_kill_args), (sy_call_t *)linux_kill, AUE_KILL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 62 = linux_kill */
+ { AS(linux_newuname_args), (sy_call_t *)linux_newuname, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 63 = linux_newuname */
+ { AS(linux_semget_args), (sy_call_t *)linux_semget, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 64 = linux_semget */
+ { AS(linux_semop_args), (sy_call_t *)linux_semop, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 65 = linux_semop */
+ { AS(linux_semctl_args), (sy_call_t *)linux_semctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 66 = linux_semctl */
+ { AS(linux_shmdt_args), (sy_call_t *)linux_shmdt, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 67 = linux_shmdt */
+ { AS(linux_msgget_args), (sy_call_t *)linux_msgget, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 68 = linux_msgget */
+ { AS(linux_msgsnd_args), (sy_call_t *)linux_msgsnd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 69 = linux_msgsnd */
+ { AS(linux_msgrcv_args), (sy_call_t *)linux_msgrcv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 70 = linux_msgrcv */
+ { AS(linux_msgctl_args), (sy_call_t *)linux_msgctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 71 = linux_msgctl */
+ { AS(linux_fcntl_args), (sy_call_t *)linux_fcntl, AUE_FCNTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 72 = linux_fcntl */
+ { AS(flock_args), (sy_call_t *)sys_flock, AUE_FLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 73 = flock */
+ { AS(fsync_args), (sy_call_t *)sys_fsync, AUE_FSYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 74 = fsync */
+ { AS(linux_fdatasync_args), (sy_call_t *)linux_fdatasync, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 75 = linux_fdatasync */
+ { AS(linux_truncate_args), (sy_call_t *)linux_truncate, AUE_TRUNCATE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 76 = linux_truncate */
+ { AS(linux_ftruncate_args), (sy_call_t *)linux_ftruncate, AUE_FTRUNCATE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 77 = linux_ftruncate */
+ { AS(linux_getdents_args), (sy_call_t *)linux_getdents, AUE_GETDIRENTRIES, NULL, 0, 0, 0, SY_THR_STATIC }, /* 78 = linux_getdents */
+ { AS(linux_getcwd_args), (sy_call_t *)linux_getcwd, AUE_GETCWD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 79 = linux_getcwd */
+ { AS(linux_chdir_args), (sy_call_t *)linux_chdir, AUE_CHDIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 80 = linux_chdir */
+ { AS(fchdir_args), (sy_call_t *)sys_fchdir, AUE_FCHDIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 81 = fchdir */
+ { AS(linux_rename_args), (sy_call_t *)linux_rename, AUE_RENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 82 = linux_rename */
+ { AS(linux_mkdir_args), (sy_call_t *)linux_mkdir, AUE_MKDIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 83 = linux_mkdir */
+ { AS(linux_rmdir_args), (sy_call_t *)linux_rmdir, AUE_RMDIR, NULL, 0, 0, 0, SY_THR_STATIC }, /* 84 = linux_rmdir */
+ { AS(linux_creat_args), (sy_call_t *)linux_creat, AUE_CREAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 85 = linux_creat */
+ { AS(linux_link_args), (sy_call_t *)linux_link, AUE_LINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 86 = linux_link */
+ { AS(linux_unlink_args), (sy_call_t *)linux_unlink, AUE_UNLINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 87 = linux_unlink */
+ { AS(linux_symlink_args), (sy_call_t *)linux_symlink, AUE_SYMLINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 88 = linux_symlink */
+ { AS(linux_readlink_args), (sy_call_t *)linux_readlink, AUE_READLINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 89 = linux_readlink */
+ { AS(linux_chmod_args), (sy_call_t *)linux_chmod, AUE_CHMOD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 90 = linux_chmod */
+ { AS(fchmod_args), (sy_call_t *)sys_fchmod, AUE_FCHMOD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 91 = fchmod */
+ { AS(linux_chown_args), (sy_call_t *)linux_chown, AUE_LCHOWN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 92 = linux_chown */
+ { AS(fchown_args), (sy_call_t *)sys_fchown, AUE_FCHOWN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 93 = fchown */
+ { AS(linux_lchown_args), (sy_call_t *)linux_lchown, AUE_LCHOWN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 94 = linux_lchown */
+ { AS(umask_args), (sy_call_t *)sys_umask, AUE_UMASK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 95 = umask */
+ { AS(gettimeofday_args), (sy_call_t *)sys_gettimeofday, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 96 = gettimeofday */
+ { AS(linux_getrlimit_args), (sy_call_t *)linux_getrlimit, AUE_GETRLIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 97 = linux_getrlimit */
+ { AS(getrusage_args), (sy_call_t *)sys_getrusage, AUE_GETRUSAGE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 98 = getrusage */
+ { AS(linux_sysinfo_args), (sy_call_t *)linux_sysinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 99 = linux_sysinfo */
+ { AS(linux_times_args), (sy_call_t *)linux_times, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 100 = linux_times */
+ { AS(linux_ptrace_args), (sy_call_t *)linux_ptrace, AUE_PTRACE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 101 = linux_ptrace */
+ { 0, (sy_call_t *)linux_getuid, AUE_GETUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 102 = linux_getuid */
+ { AS(linux_syslog_args), (sy_call_t *)linux_syslog, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 103 = linux_syslog */
+ { 0, (sy_call_t *)linux_getgid, AUE_GETGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 104 = linux_getgid */
+ { AS(setuid_args), (sy_call_t *)sys_setuid, AUE_SETUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 105 = setuid */
+ { AS(setgid_args), (sy_call_t *)sys_setgid, AUE_SETGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 106 = setgid */
+ { 0, (sy_call_t *)sys_geteuid, AUE_GETEUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 107 = geteuid */
+ { 0, (sy_call_t *)sys_getegid, AUE_GETEGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 108 = getegid */
+ { AS(setpgid_args), (sy_call_t *)sys_setpgid, AUE_SETPGRP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 109 = setpgid */
+ { 0, (sy_call_t *)linux_getppid, AUE_GETPPID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 110 = linux_getppid */
+ { 0, (sy_call_t *)sys_getpgrp, AUE_GETPGRP, NULL, 0, 0, 0, SY_THR_STATIC }, /* 111 = getpgrp */
+ { 0, (sy_call_t *)sys_setsid, AUE_SETSID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 112 = setsid */
+ { AS(setreuid_args), (sy_call_t *)sys_setreuid, AUE_SETREUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 113 = setreuid */
+ { AS(setregid_args), (sy_call_t *)sys_setregid, AUE_SETREGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 114 = setregid */
+ { AS(linux_getgroups_args), (sy_call_t *)linux_getgroups, AUE_GETGROUPS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 115 = linux_getgroups */
+ { AS(linux_setgroups_args), (sy_call_t *)linux_setgroups, AUE_SETGROUPS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 116 = linux_setgroups */
+ { AS(setresuid_args), (sy_call_t *)sys_setresuid, AUE_SETRESUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 117 = setresuid */
+ { AS(getresuid_args), (sy_call_t *)sys_getresuid, AUE_GETRESUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 118 = getresuid */
+ { AS(setresgid_args), (sy_call_t *)sys_setresgid, AUE_SETRESGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 119 = setresgid */
+ { AS(getresgid_args), (sy_call_t *)sys_getresgid, AUE_GETRESGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 120 = getresgid */
+ { AS(getpgid_args), (sy_call_t *)sys_getpgid, AUE_GETPGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 121 = getpgid */
+ { AS(linux_setfsuid_args), (sy_call_t *)linux_setfsuid, AUE_SETFSUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 122 = linux_setfsuid */
+ { AS(linux_setfsgid_args), (sy_call_t *)linux_setfsgid, AUE_SETFSGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 123 = linux_setfsgid */
+ { AS(linux_getsid_args), (sy_call_t *)linux_getsid, AUE_GETSID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 124 = linux_getsid */
+ { AS(linux_capget_args), (sy_call_t *)linux_capget, AUE_CAPGET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 125 = linux_capget */
+ { AS(linux_capset_args), (sy_call_t *)linux_capset, AUE_CAPSET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 126 = linux_capset */
+ { AS(linux_rt_sigpending_args), (sy_call_t *)linux_rt_sigpending, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 127 = linux_rt_sigpending */
+ { AS(linux_rt_sigtimedwait_args), (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 128 = linux_rt_sigtimedwait */
+ { AS(linux_rt_sigqueueinfo_args), (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 129 = linux_rt_sigqueueinfo */
+ { AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 130 = linux_rt_sigsuspend */
+ { AS(linux_sigaltstack_args), (sy_call_t *)linux_sigaltstack, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 131 = linux_sigaltstack */
+ { AS(linux_utime_args), (sy_call_t *)linux_utime, AUE_UTIME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 132 = linux_utime */
+ { AS(linux_mknod_args), (sy_call_t *)linux_mknod, AUE_MKNOD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 133 = linux_mknod */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 134 = uselib */
+ { AS(linux_personality_args), (sy_call_t *)linux_personality, AUE_PERSONALITY, NULL, 0, 0, 0, SY_THR_STATIC }, /* 135 = linux_personality */
+ { AS(linux_ustat_args), (sy_call_t *)linux_ustat, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 136 = linux_ustat */
+ { AS(linux_statfs_args), (sy_call_t *)linux_statfs, AUE_STATFS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 137 = linux_statfs */
+ { AS(linux_fstatfs_args), (sy_call_t *)linux_fstatfs, AUE_FSTATFS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 138 = linux_fstatfs */
+ { AS(linux_sysfs_args), (sy_call_t *)linux_sysfs, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 139 = linux_sysfs */
+ { AS(linux_getpriority_args), (sy_call_t *)linux_getpriority, AUE_GETPRIORITY, NULL, 0, 0, 0, SY_THR_STATIC }, /* 140 = linux_getpriority */
+ { AS(setpriority_args), (sy_call_t *)sys_setpriority, AUE_SETPRIORITY, NULL, 0, 0, 0, SY_THR_STATIC }, /* 141 = setpriority */
+ { AS(linux_sched_setparam_args), (sy_call_t *)linux_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 142 = linux_sched_setparam */
+ { AS(linux_sched_getparam_args), (sy_call_t *)linux_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 143 = linux_sched_getparam */
+ { AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler, AUE_SCHED_SETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 144 = linux_sched_setscheduler */
+ { AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler, AUE_SCHED_GETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 145 = linux_sched_getscheduler */
+ { AS(linux_sched_get_priority_max_args), (sy_call_t *)linux_sched_get_priority_max, AUE_SCHED_GET_PRIORITY_MAX, NULL, 0, 0, 0, SY_THR_STATIC }, /* 146 = linux_sched_get_priority_max */
+ { AS(linux_sched_get_priority_min_args), (sy_call_t *)linux_sched_get_priority_min, AUE_SCHED_GET_PRIORITY_MIN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 147 = linux_sched_get_priority_min */
+ { AS(linux_sched_rr_get_interval_args), (sy_call_t *)linux_sched_rr_get_interval, AUE_SCHED_RR_GET_INTERVAL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 148 = linux_sched_rr_get_interval */
+ { AS(mlock_args), (sy_call_t *)sys_mlock, AUE_MLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 149 = mlock */
+ { AS(munlock_args), (sy_call_t *)sys_munlock, AUE_MUNLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 150 = munlock */
+ { AS(mlockall_args), (sy_call_t *)sys_mlockall, AUE_MLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 151 = mlockall */
+ { 0, (sy_call_t *)sys_munlockall, AUE_MUNLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 152 = munlockall */
+ { 0, (sy_call_t *)linux_vhangup, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 153 = linux_vhangup */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 154 = modify_ldt */
+ { 0, (sy_call_t *)linux_pivot_root, AUE_PIVOT_ROOT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = linux_pivot_root */
+ { AS(linux_sysctl_args), (sy_call_t *)linux_sysctl, AUE_SYSCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 156 = linux_sysctl */
+ { AS(linux_prctl_args), (sy_call_t *)linux_prctl, AUE_PRCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 157 = linux_prctl */
+ { AS(linux_arch_prctl_args), (sy_call_t *)linux_arch_prctl, AUE_PRCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 158 = linux_arch_prctl */
+ { 0, (sy_call_t *)linux_adjtimex, AUE_ADJTIME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 159 = linux_adjtimex */
+ { AS(linux_setrlimit_args), (sy_call_t *)linux_setrlimit, AUE_SETRLIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 160 = linux_setrlimit */
+ { AS(chroot_args), (sy_call_t *)sys_chroot, AUE_CHROOT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 161 = chroot */
+ { 0, (sy_call_t *)sys_sync, AUE_SYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 162 = sync */
+ { AS(acct_args), (sy_call_t *)sys_acct, AUE_ACCT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 163 = acct */
+ { AS(settimeofday_args), (sy_call_t *)sys_settimeofday, AUE_SETTIMEOFDAY, NULL, 0, 0, 0, SY_THR_STATIC }, /* 164 = settimeofday */
+ { AS(linux_mount_args), (sy_call_t *)linux_mount, AUE_MOUNT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 165 = linux_mount */
+ { AS(linux_umount_args), (sy_call_t *)linux_umount, AUE_UMOUNT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 166 = linux_umount */
+ { AS(swapon_args), (sy_call_t *)sys_swapon, AUE_SWAPON, NULL, 0, 0, 0, SY_THR_STATIC }, /* 167 = swapon */
+ { 0, (sy_call_t *)linux_swapoff, AUE_SWAPOFF, NULL, 0, 0, 0, SY_THR_STATIC }, /* 168 = linux_swapoff */
+ { AS(linux_reboot_args), (sy_call_t *)linux_reboot, AUE_REBOOT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 169 = linux_reboot */
+ { AS(linux_sethostname_args), (sy_call_t *)linux_sethostname, AUE_SYSCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 170 = linux_sethostname */
+ { AS(linux_setdomainname_args), (sy_call_t *)linux_setdomainname, AUE_SYSCTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 171 = linux_setdomainname */
+ { AS(linux_iopl_args), (sy_call_t *)linux_iopl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 172 = linux_iopl */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 173 = ioperm */
+ { 0, (sy_call_t *)linux_create_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 174 = linux_create_module */
+ { 0, (sy_call_t *)linux_init_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 175 = linux_init_module */
+ { 0, (sy_call_t *)linux_delete_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 176 = linux_delete_module */
+ { 0, (sy_call_t *)linux_get_kernel_syms, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 177 = linux_get_kernel_syms */
+ { 0, (sy_call_t *)linux_query_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_query_module */
+ { 0, (sy_call_t *)linux_quotactl, AUE_QUOTACTL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 179 = linux_quotactl */
+ { 0, (sy_call_t *)linux_nfsservctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 180 = linux_nfsservctl */
+ { 0, (sy_call_t *)linux_getpmsg, AUE_GETPMSG, NULL, 0, 0, 0, SY_THR_STATIC }, /* 181 = linux_getpmsg */
+ { 0, (sy_call_t *)linux_putpmsg, AUE_PUTPMSG, NULL, 0, 0, 0, SY_THR_STATIC }, /* 182 = linux_putpmsg */
+ { 0, (sy_call_t *)linux_afs_syscall, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 183 = linux_afs_syscall */
+ { 0, (sy_call_t *)linux_tuxcall, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 184 = linux_tuxcall */
+ { 0, (sy_call_t *)linux_security, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 185 = linux_security */
+ { 0, (sy_call_t *)linux_gettid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 186 = linux_gettid */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 187 = linux_readahead */
+ { 0, (sy_call_t *)linux_setxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 188 = linux_setxattr */
+ { 0, (sy_call_t *)linux_lsetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 189 = linux_lsetxattr */
+ { 0, (sy_call_t *)linux_fsetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 190 = linux_fsetxattr */
+ { 0, (sy_call_t *)linux_getxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 191 = linux_getxattr */
+ { 0, (sy_call_t *)linux_lgetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 192 = linux_lgetxattr */
+ { 0, (sy_call_t *)linux_fgetxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 193 = linux_fgetxattr */
+ { 0, (sy_call_t *)linux_listxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 194 = linux_listxattr */
+ { 0, (sy_call_t *)linux_llistxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 195 = linux_llistxattr */
+ { 0, (sy_call_t *)linux_flistxattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 196 = linux_flistxattr */
+ { 0, (sy_call_t *)linux_removexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 197 = linux_removexattr */
+ { 0, (sy_call_t *)linux_lremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 198 = linux_lremovexattr */
+ { 0, (sy_call_t *)linux_fremovexattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 199 = linux_fremovexattr */
+ { AS(linux_tkill_args), (sy_call_t *)linux_tkill, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 200 = linux_tkill */
+ { AS(linux_time_args), (sy_call_t *)linux_time, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 201 = linux_time */
+ { AS(linux_sys_futex_args), (sy_call_t *)linux_sys_futex, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 202 = linux_sys_futex */
+ { AS(linux_sched_setaffinity_args), (sy_call_t *)linux_sched_setaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 203 = linux_sched_setaffinity */
+ { AS(linux_sched_getaffinity_args), (sy_call_t *)linux_sched_getaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 204 = linux_sched_getaffinity */
+ { 0, (sy_call_t *)linux_set_thread_area, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 205 = linux_set_thread_area */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 206 = linux_io_setup */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 207 = linux_io_destroy */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 208 = linux_io_getevents */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 209 = inux_io_submit */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 210 = linux_io_cancel */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 211 = linux_get_thread_area */
+ { 0, (sy_call_t *)linux_lookup_dcookie, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 212 = linux_lookup_dcookie */
+ { AS(linux_epoll_create_args), (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 213 = linux_epoll_create */
+ { 0, (sy_call_t *)linux_epoll_ctl_old, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 214 = linux_epoll_ctl_old */
+ { 0, (sy_call_t *)linux_epoll_wait_old, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 215 = linux_epoll_wait_old */
+ { 0, (sy_call_t *)linux_remap_file_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 216 = linux_remap_file_pages */
+ { AS(linux_getdents64_args), (sy_call_t *)linux_getdents64, AUE_GETDIRENTRIES, NULL, 0, 0, 0, SY_THR_STATIC }, /* 217 = linux_getdents64 */
+ { AS(linux_set_tid_address_args), (sy_call_t *)linux_set_tid_address, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 218 = linux_set_tid_address */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 219 = restart_syscall */
+ { 0, (sy_call_t *)linux_semtimedop, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 220 = linux_semtimedop */
+ { AS(linux_fadvise64_args), (sy_call_t *)linux_fadvise64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 221 = linux_fadvise64 */
+ { AS(linux_timer_create_args), (sy_call_t *)linux_timer_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 222 = linux_timer_create */
+ { AS(linux_timer_settime_args), (sy_call_t *)linux_timer_settime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 223 = linux_timer_settime */
+ { AS(linux_timer_gettime_args), (sy_call_t *)linux_timer_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 224 = linux_timer_gettime */
+ { AS(linux_timer_getoverrun_args), (sy_call_t *)linux_timer_getoverrun, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 225 = linux_timer_getoverrun */
+ { AS(linux_timer_delete_args), (sy_call_t *)linux_timer_delete, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 226 = linux_timer_delete */
+ { AS(linux_clock_settime_args), (sy_call_t *)linux_clock_settime, AUE_CLOCK_SETTIME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 227 = linux_clock_settime */
+ { AS(linux_clock_gettime_args), (sy_call_t *)linux_clock_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 228 = linux_clock_gettime */
+ { AS(linux_clock_getres_args), (sy_call_t *)linux_clock_getres, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 229 = linux_clock_getres */
+ { AS(linux_clock_nanosleep_args), (sy_call_t *)linux_clock_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 230 = linux_clock_nanosleep */
+ { AS(linux_exit_group_args), (sy_call_t *)linux_exit_group, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 231 = linux_exit_group */
+ { AS(linux_epoll_wait_args), (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 232 = linux_epoll_wait */
+ { AS(linux_epoll_ctl_args), (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 233 = linux_epoll_ctl */
+ { AS(linux_tgkill_args), (sy_call_t *)linux_tgkill, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 234 = linux_tgkill */
+ { AS(linux_utimes_args), (sy_call_t *)linux_utimes, AUE_UTIMES, NULL, 0, 0, 0, SY_THR_STATIC }, /* 235 = linux_utimes */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 236 = vserver */
+ { 0, (sy_call_t *)linux_mbind, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 237 = linux_mbind */
+ { 0, (sy_call_t *)linux_set_mempolicy, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 238 = linux_set_mempolicy */
+ { 0, (sy_call_t *)linux_get_mempolicy, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 239 = linux_get_mempolicy */
+ { 0, (sy_call_t *)linux_mq_open, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 240 = linux_mq_open */
+ { 0, (sy_call_t *)linux_mq_unlink, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 241 = linux_mq_unlink */
+ { 0, (sy_call_t *)linux_mq_timedsend, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 242 = linux_mq_timedsend */
+ { 0, (sy_call_t *)linux_mq_timedreceive, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 243 = linux_mq_timedreceive */
+ { 0, (sy_call_t *)linux_mq_notify, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 244 = linux_mq_notify */
+ { 0, (sy_call_t *)linux_mq_getsetattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 245 = linux_mq_getsetattr */
+ { 0, (sy_call_t *)linux_kexec_load, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 246 = linux_kexec_load */
+ { AS(linux_waitid_args), (sy_call_t *)linux_waitid, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 247 = linux_waitid */
+ { 0, (sy_call_t *)linux_add_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 248 = linux_add_key */
+ { 0, (sy_call_t *)linux_request_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 249 = linux_request_key */
+ { 0, (sy_call_t *)linux_keyctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 250 = linux_keyctl */
+ { 0, (sy_call_t *)linux_ioprio_set, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 251 = linux_ioprio_set */
+ { 0, (sy_call_t *)linux_ioprio_get, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 252 = linux_ioprio_get */
+ { 0, (sy_call_t *)linux_inotify_init, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 253 = linux_inotify_init */
+ { 0, (sy_call_t *)linux_inotify_add_watch, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_inotify_add_watch */
+ { 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_inotify_rm_watch */
+ { 0, (sy_call_t *)linux_migrate_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_migrate_pages */
+ { AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_OPEN_RWTC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 257 = linux_openat */
+ { AS(linux_mkdirat_args), (sy_call_t *)linux_mkdirat, AUE_MKDIRAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 258 = linux_mkdirat */
+ { AS(linux_mknodat_args), (sy_call_t *)linux_mknodat, AUE_MKNODAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 259 = linux_mknodat */
+ { AS(linux_fchownat_args), (sy_call_t *)linux_fchownat, AUE_FCHOWNAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 260 = linux_fchownat */
+ { AS(linux_futimesat_args), (sy_call_t *)linux_futimesat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 261 = linux_futimesat */
+ { AS(linux_newfstatat_args), (sy_call_t *)linux_newfstatat, AUE_FSTATAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 262 = linux_newfstatat */
+ { AS(linux_unlinkat_args), (sy_call_t *)linux_unlinkat, AUE_UNLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 263 = linux_unlinkat */
+ { AS(linux_renameat_args), (sy_call_t *)linux_renameat, AUE_RENAMEAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 264 = linux_renameat */
+ { AS(linux_linkat_args), (sy_call_t *)linux_linkat, AUE_LINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 265 = linux_linkat */
+ { AS(linux_symlinkat_args), (sy_call_t *)linux_symlinkat, AUE_SYMLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 266 = linux_symlinkat */
+ { AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_READLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 267 = linux_readlinkat */
+ { AS(linux_fchmodat_args), (sy_call_t *)linux_fchmodat, AUE_FCHMODAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 268 = linux_fchmodat */
+ { AS(linux_faccessat_args), (sy_call_t *)linux_faccessat, AUE_FACCESSAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 269 = linux_faccessat */
+ { AS(linux_pselect6_args), (sy_call_t *)linux_pselect6, AUE_SELECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 270 = linux_pselect6 */
+ { AS(linux_ppoll_args), (sy_call_t *)linux_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 271 = linux_ppoll */
+ { 0, (sy_call_t *)linux_unshare, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 272 = linux_unshare */
+ { AS(linux_set_robust_list_args), (sy_call_t *)linux_set_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 273 = linux_set_robust_list */
+ { AS(linux_get_robust_list_args), (sy_call_t *)linux_get_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 274 = linux_get_robust_list */
+ { 0, (sy_call_t *)linux_splice, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 275 = linux_splice */
+ { 0, (sy_call_t *)linux_tee, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 276 = linux_tee */
+ { 0, (sy_call_t *)linux_sync_file_range, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 277 = linux_sync_file_range */
+ { 0, (sy_call_t *)linux_vmsplice, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 278 = linux_vmsplice */
+ { 0, (sy_call_t *)linux_move_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 279 = linux_move_pages */
+ { AS(linux_utimensat_args), (sy_call_t *)linux_utimensat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 280 = linux_utimensat */
+ { AS(linux_epoll_pwait_args), (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 281 = linux_epoll_pwait */
+ { 0, (sy_call_t *)linux_signalfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 282 = linux_signalfd */
+ { 0, (sy_call_t *)linux_timerfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 283 = linux_timerfd */
+ { AS(linux_eventfd_args), (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_eventfd */
+ { AS(linux_fallocate_args), (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 285 = linux_fallocate */
+ { 0, (sy_call_t *)linux_timerfd_settime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 286 = linux_timerfd_settime */
+ { 0, (sy_call_t *)linux_timerfd_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 287 = linux_timerfd_gettime */
+ { AS(linux_accept4_args), (sy_call_t *)linux_accept4, AUE_ACCEPT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 288 = linux_accept4 */
+ { 0, (sy_call_t *)linux_signalfd4, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 289 = linux_signalfd4 */
+ { AS(linux_eventfd2_args), (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 290 = linux_eventfd2 */
+ { AS(linux_epoll_create1_args), (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 291 = linux_epoll_create1 */
+ { AS(linux_dup3_args), (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 292 = linux_dup3 */
+ { AS(linux_pipe2_args), (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 293 = linux_pipe2 */
+ { 0, (sy_call_t *)linux_inotify_init1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 294 = linux_inotify_init1 */
+ { 0, (sy_call_t *)linux_preadv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 295 = linux_preadv */
+ { 0, (sy_call_t *)linux_pwritev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 296 = linux_pwritev */
+ { 0, (sy_call_t *)linux_rt_tsigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 297 = linux_rt_tsigqueueinfo */
+ { 0, (sy_call_t *)linux_perf_event_open, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 298 = linux_perf_event_open */
+ { AS(linux_recvmmsg_args), (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 299 = linux_recvmmsg */
+ { 0, (sy_call_t *)linux_fanotify_init, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 300 = linux_fanotify_init */
+ { 0, (sy_call_t *)linux_fanotify_mark, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 301 = linux_fanotify_mark */
+ { AS(linux_prlimit64_args), (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 302 = linux_prlimit64 */
+ { 0, (sy_call_t *)linux_name_to_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 303 = linux_name_to_handle_at */
+ { 0, (sy_call_t *)linux_open_by_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 304 = linux_open_by_handle_at */
+ { 0, (sy_call_t *)linux_clock_adjtime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 305 = linux_clock_adjtime */
+ { AS(linux_syncfs_args), (sy_call_t *)linux_syncfs, AUE_SYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 306 = linux_syncfs */
+ { AS(linux_sendmmsg_args), (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 307 = linux_sendmmsg */
+ { 0, (sy_call_t *)linux_setns, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_setns */
+ { 0, (sy_call_t *)linux_process_vm_readv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_process_vm_readv */
+ { 0, (sy_call_t *)linux_process_vm_writev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 310 = linux_process_vm_writev */
+ { 0, (sy_call_t *)linux_kcmp, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 311 = linux_kcmp */
+ { 0, (sy_call_t *)linux_finit_module, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 312 = linux_finit_module */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 313 = nosys */
+};
diff --git a/sys/amd64/linux/linux_systrace_args.c b/sys/amd64/linux/linux_systrace_args.c
new file mode 100644
index 000000000000..529e76883b9e
--- /dev/null
+++ b/sys/amd64/linux/linux_systrace_args.c
@@ -0,0 +1,6885 @@
+/*
+ * System call argument to DTrace register array converstion.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * $FreeBSD$
+ * This file is part of the DTrace syscall provider.
+ */
+
+static void
+systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
+{
+ int64_t *iarg = (int64_t *) uarg;
+ switch (sysnum) {
+#define nosys linux_nosys
+ /* read */
+ case 0: {
+ struct read_args *p = params;
+ iarg[0] = p->fd; /* int */
+ uarg[1] = (intptr_t) p->buf; /* char * */
+ uarg[2] = p->nbyte; /* u_int */
+ *n_args = 3;
+ break;
+ }
+ /* write */
+ case 1: {
+ struct write_args *p = params;
+ iarg[0] = p->fd; /* int */
+ uarg[1] = (intptr_t) p->buf; /* char * */
+ uarg[2] = p->nbyte; /* u_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_open */
+ case 2: {
+ struct linux_open_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->flags; /* l_int */
+ iarg[2] = p->mode; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* close */
+ case 3: {
+ struct close_args *p = params;
+ iarg[0] = p->fd; /* int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_newstat */
+ case 4: {
+ struct linux_newstat_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ uarg[1] = (intptr_t) p->buf; /* struct l_newstat * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_newfstat */
+ case 5: {
+ struct linux_newfstat_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ uarg[1] = (intptr_t) p->buf; /* struct l_newstat * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_newlstat */
+ case 6: {
+ struct linux_newlstat_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ uarg[1] = (intptr_t) p->buf; /* struct l_newstat * */
+ *n_args = 2;
+ break;
+ }
+ /* poll */
+ case 7: {
+ struct poll_args *p = params;
+ iarg[0] = p->*; /* struct pollfd */
+ uarg[1] = p->nfds; /* unsigned int */
+ iarg[2] = p->timeout; /* int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_lseek */
+ case 8: {
+ struct linux_lseek_args *p = params;
+ iarg[0] = p->fdes; /* l_uint */
+ iarg[1] = p->off; /* l_off_t */
+ iarg[2] = p->whence; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_mmap2 */
+ case 9: {
+ struct linux_mmap2_args *p = params;
+ iarg[0] = p->addr; /* l_ulong */
+ iarg[1] = p->len; /* l_ulong */
+ iarg[2] = p->prot; /* l_ulong */
+ iarg[3] = p->flags; /* l_ulong */
+ iarg[4] = p->fd; /* l_ulong */
+ iarg[5] = p->pgoff; /* l_ulong */
+ *n_args = 6;
+ break;
+ }
+ /* linux_mprotect */
+ case 10: {
+ struct linux_mprotect_args *p = params;
+ uarg[0] = (intptr_t) p->addr; /* caddr_t */
+ iarg[1] = p->len; /* int */
+ iarg[2] = p->prot; /* int */
+ *n_args = 3;
+ break;
+ }
+ /* munmap */
+ case 11: {
+ struct munmap_args *p = params;
+ uarg[0] = (intptr_t) p->addr; /* caddr_t */
+ iarg[1] = p->len; /* int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_brk */
+ case 12: {
+ struct linux_brk_args *p = params;
+ iarg[0] = p->dsend; /* l_ulong */
+ *n_args = 1;
+ break;
+ }
+ /* linux_rt_sigaction */
+ case 13: {
+ struct linux_rt_sigaction_args *p = params;
+ iarg[0] = p->sig; /* l_int */
+ uarg[1] = (intptr_t) p->act; /* l_sigaction_t * */
+ uarg[2] = (intptr_t) p->oact; /* l_sigaction_t * */
+ iarg[3] = p->sigsetsize; /* l_size_t */
+ *n_args = 4;
+ break;
+ }
+ /* linux_rt_sigprocmask */
+ case 14: {
+ struct linux_rt_sigprocmask_args *p = params;
+ iarg[0] = p->how; /* l_int */
+ uarg[1] = (intptr_t) p->mask; /* l_sigset_t * */
+ uarg[2] = (intptr_t) p->omask; /* l_sigset_t * */
+ iarg[3] = p->sigsetsize; /* l_size_t */
+ *n_args = 4;
+ break;
+ }
+ /* linux_rt_sigreturn */
+ case 15: {
+ struct linux_rt_sigreturn_args *p = params;
+ uarg[0] = (intptr_t) p->ucp; /* struct l_ucontext * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_ioctl */
+ case 16: {
+ struct linux_ioctl_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ iarg[1] = p->cmd; /* l_uint */
+ uarg[2] = p->arg; /* uintptr_t */
+ *n_args = 3;
+ break;
+ }
+ /* linux_pread */
+ case 17: {
+ struct linux_pread_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ uarg[1] = (intptr_t) p->buf; /* char * */
+ iarg[2] = p->nbyte; /* l_size_t */
+ iarg[3] = p->offset; /* l_loff_t */
+ *n_args = 4;
+ break;
+ }
+ /* linux_pwrite */
+ case 18: {
+ struct linux_pwrite_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ uarg[1] = (intptr_t) p->buf; /* char * */
+ iarg[2] = p->nbyte; /* l_size_t */
+ iarg[3] = p->offset; /* l_loff_t */
+ *n_args = 4;
+ break;
+ }
+ /* readv */
+ case 19: {
+ struct readv_args *p = params;
+ iarg[0] = p->fd; /* int */
+ uarg[1] = (intptr_t) p->iovp; /* struct iovec * */
+ uarg[2] = p->iovcnt; /* u_int */
+ *n_args = 3;
+ break;
+ }
+ /* writev */
+ case 20: {
+ struct writev_args *p = params;
+ iarg[0] = p->fd; /* int */
+ uarg[1] = (intptr_t) p->iovp; /* struct iovec * */
+ uarg[2] = p->iovcnt; /* u_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_access */
+ case 21: {
+ struct linux_access_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->amode; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_pipe */
+ case 22: {
+ struct linux_pipe_args *p = params;
+ uarg[0] = (intptr_t) p->pipefds; /* l_ulong * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_select */
+ case 23: {
+ struct linux_select_args *p = params;
+ iarg[0] = p->nfds; /* l_int */
+ uarg[1] = (intptr_t) p->readfds; /* l_fd_set * */
+ uarg[2] = (intptr_t) p->writefds; /* l_fd_set * */
+ uarg[3] = (intptr_t) p->exceptfds; /* l_fd_set * */
+ uarg[4] = (intptr_t) p->timeout; /* struct l_timeval * */
+ *n_args = 5;
+ break;
+ }
+ /* sched_yield */
+ case 24: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_mremap */
+ case 25: {
+ struct linux_mremap_args *p = params;
+ iarg[0] = p->addr; /* l_ulong */
+ iarg[1] = p->old_len; /* l_ulong */
+ iarg[2] = p->new_len; /* l_ulong */
+ iarg[3] = p->flags; /* l_ulong */
+ iarg[4] = p->new_addr; /* l_ulong */
+ *n_args = 5;
+ break;
+ }
+ /* linux_msync */
+ case 26: {
+ struct linux_msync_args *p = params;
+ iarg[0] = p->addr; /* l_ulong */
+ iarg[1] = p->len; /* l_size_t */
+ iarg[2] = p->fl; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_mincore */
+ case 27: {
+ struct linux_mincore_args *p = params;
+ iarg[0] = p->start; /* l_ulong */
+ iarg[1] = p->len; /* l_size_t */
+ uarg[2] = (intptr_t) p->vec; /* u_char * */
+ *n_args = 3;
+ break;
+ }
+ /* madvise */
+ case 28: {
+ struct madvise_args *p = params;
+ uarg[0] = (intptr_t) p->addr; /* void * */
+ uarg[1] = p->len; /* size_t */
+ iarg[2] = p->behav; /* int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_shmget */
+ case 29: {
+ struct linux_shmget_args *p = params;
+ iarg[0] = p->key; /* l_key_t */
+ iarg[1] = p->size; /* l_size_t */
+ iarg[2] = p->shmflg; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_shmat */
+ case 30: {
+ struct linux_shmat_args *p = params;
+ iarg[0] = p->shmid; /* l_int */
+ uarg[1] = (intptr_t) p->shmaddr; /* char * */
+ iarg[2] = p->shmflg; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_shmctl */
+ case 31: {
+ struct linux_shmctl_args *p = params;
+ iarg[0] = p->shmid; /* l_int */
+ iarg[1] = p->cmd; /* l_int */
+ uarg[2] = (intptr_t) p->buf; /* struct l_shmid_ds * */
+ *n_args = 3;
+ break;
+ }
+ /* dup */
+ case 32: {
+ struct dup_args *p = params;
+ uarg[0] = p->fd; /* u_int */
+ *n_args = 1;
+ break;
+ }
+ /* dup2 */
+ case 33: {
+ struct dup2_args *p = params;
+ uarg[0] = p->from; /* u_int */
+ uarg[1] = p->to; /* u_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_pause */
+ case 34: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_nanosleep */
+ case 35: {
+ struct linux_nanosleep_args *p = params;
+ uarg[0] = (intptr_t) p->rqtp; /* const struct l_timespec * */
+ uarg[1] = (intptr_t) p->rmtp; /* struct l_timespec * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_getitimer */
+ case 36: {
+ struct linux_getitimer_args *p = params;
+ iarg[0] = p->which; /* l_int */
+ uarg[1] = (intptr_t) p->itv; /* struct l_itimerval * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_alarm */
+ case 37: {
+ struct linux_alarm_args *p = params;
+ iarg[0] = p->secs; /* l_uint */
+ *n_args = 1;
+ break;
+ }
+ /* linux_setitimer */
+ case 38: {
+ struct linux_setitimer_args *p = params;
+ iarg[0] = p->which; /* l_int */
+ uarg[1] = (intptr_t) p->itv; /* struct l_itimerval * */
+ uarg[2] = (intptr_t) p->oitv; /* struct l_itimerval * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_getpid */
+ case 39: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_sendfile */
+ case 40: {
+ struct linux_sendfile_args *p = params;
+ iarg[0] = p->out; /* int */
+ iarg[1] = p->in; /* int */
+ uarg[2] = (intptr_t) p->offset; /* l_long * */
+ iarg[3] = p->count; /* l_size_t */
+ *n_args = 4;
+ break;
+ }
+ /* linux_socket */
+ case 41: {
+ struct linux_socket_args *p = params;
+ iarg[0] = p->domain; /* l_int */
+ iarg[1] = p->type; /* l_int */
+ iarg[2] = p->protocol; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_connect */
+ case 42: {
+ struct linux_connect_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->name; /* l_uintptr_t */
+ iarg[2] = p->namelen; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_accept */
+ case 43: {
+ struct linux_accept_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->addr; /* l_uintptr_t */
+ iarg[2] = p->namelen; /* l_uintptr_t */
+ *n_args = 3;
+ break;
+ }
+ /* linux_sendto */
+ case 44: {
+ struct linux_sendto_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->msg; /* l_uintptr_t */
+ iarg[2] = p->len; /* l_int */
+ iarg[3] = p->flags; /* l_int */
+ iarg[4] = p->to; /* l_uintptr_t */
+ iarg[5] = p->tolen; /* l_int */
+ *n_args = 6;
+ break;
+ }
+ /* linux_recvfrom */
+ case 45: {
+ struct linux_recvfrom_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->buf; /* l_uintptr_t */
+ iarg[2] = p->len; /* l_size_t */
+ iarg[3] = p->flags; /* l_int */
+ iarg[4] = p->from; /* l_uintptr_t */
+ iarg[5] = p->fromlen; /* l_uintptr_t */
+ *n_args = 6;
+ break;
+ }
+ /* linux_sendmsg */
+ case 46: {
+ struct linux_sendmsg_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->msg; /* l_uintptr_t */
+ iarg[2] = p->flags; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_recvmsg */
+ case 47: {
+ struct linux_recvmsg_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->msg; /* l_uintptr_t */
+ iarg[2] = p->flags; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_shutdown */
+ case 48: {
+ struct linux_shutdown_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->how; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_bind */
+ case 49: {
+ struct linux_bind_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->name; /* l_uintptr_t */
+ iarg[2] = p->namelen; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_listen */
+ case 50: {
+ struct linux_listen_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->backlog; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_getsockname */
+ case 51: {
+ struct linux_getsockname_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->addr; /* l_uintptr_t */
+ iarg[2] = p->namelen; /* l_uintptr_t */
+ *n_args = 3;
+ break;
+ }
+ /* linux_getpeername */
+ case 52: {
+ struct linux_getpeername_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->addr; /* l_uintptr_t */
+ iarg[2] = p->namelen; /* l_uintptr_t */
+ *n_args = 3;
+ break;
+ }
+ /* linux_socketpair */
+ case 53: {
+ struct linux_socketpair_args *p = params;
+ iarg[0] = p->domain; /* l_int */
+ iarg[1] = p->type; /* l_int */
+ iarg[2] = p->protocol; /* l_int */
+ iarg[3] = p->rsv; /* l_uintptr_t */
+ *n_args = 4;
+ break;
+ }
+ /* linux_setsockopt */
+ case 54: {
+ struct linux_setsockopt_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->level; /* l_int */
+ iarg[2] = p->optname; /* l_int */
+ iarg[3] = p->optval; /* l_uintptr_t */
+ iarg[4] = p->optlen; /* l_int */
+ *n_args = 5;
+ break;
+ }
+ /* linux_getsockopt */
+ case 55: {
+ struct linux_getsockopt_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->level; /* l_int */
+ iarg[2] = p->optname; /* l_int */
+ iarg[3] = p->optval; /* l_uintptr_t */
+ iarg[4] = p->optlen; /* l_uintptr_t */
+ *n_args = 5;
+ break;
+ }
+ /* linux_clone */
+ case 56: {
+ struct linux_clone_args *p = params;
+ iarg[0] = p->flags; /* l_int */
+ uarg[1] = (intptr_t) p->stack; /* void * */
+ uarg[2] = (intptr_t) p->parent_tidptr; /* void * */
+ uarg[3] = (intptr_t) p->child_tidptr; /* void * */
+ uarg[4] = (intptr_t) p->tls; /* void * */
+ *n_args = 5;
+ break;
+ }
+ /* linux_fork */
+ case 57: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_vfork */
+ case 58: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_execve */
+ case 59: {
+ struct linux_execve_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ uarg[1] = (intptr_t) p->argp; /* char ** */
+ uarg[2] = (intptr_t) p->envp; /* char ** */
+ *n_args = 3;
+ break;
+ }
+ /* linux_exit */
+ case 60: {
+ struct linux_exit_args *p = params;
+ iarg[0] = p->rval; /* int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_wait4 */
+ case 61: {
+ struct linux_wait4_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ uarg[1] = (intptr_t) p->status; /* l_int * */
+ iarg[2] = p->options; /* l_int */
+ uarg[3] = (intptr_t) p->rusage; /* struct rusage * */
+ *n_args = 4;
+ break;
+ }
+ /* linux_kill */
+ case 62: {
+ struct linux_kill_args *p = params;
+ iarg[0] = p->pid; /* l_int */
+ iarg[1] = p->signum; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_newuname */
+ case 63: {
+ struct linux_newuname_args *p = params;
+ uarg[0] = (intptr_t) p->buf; /* struct l_new_utsname * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_semget */
+ case 64: {
+ struct linux_semget_args *p = params;
+ iarg[0] = p->key; /* l_key_t */
+ iarg[1] = p->nsems; /* l_int */
+ iarg[2] = p->semflg; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_semop */
+ case 65: {
+ struct linux_semop_args *p = params;
+ iarg[0] = p->semid; /* l_int */
+ uarg[1] = (intptr_t) p->tsops; /* struct l_sembuf * */
+ iarg[2] = p->nsops; /* l_uint */
+ *n_args = 3;
+ break;
+ }
+ /* linux_semctl */
+ case 66: {
+ struct linux_semctl_args *p = params;
+ iarg[0] = p->semid; /* l_int */
+ iarg[1] = p->semnum; /* l_int */
+ iarg[2] = p->cmd; /* l_int */
+ uarg[3] = p->arg; /* union l_semun */
+ *n_args = 4;
+ break;
+ }
+ /* linux_shmdt */
+ case 67: {
+ struct linux_shmdt_args *p = params;
+ uarg[0] = (intptr_t) p->shmaddr; /* char * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_msgget */
+ case 68: {
+ struct linux_msgget_args *p = params;
+ iarg[0] = p->key; /* l_key_t */
+ iarg[1] = p->msgflg; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_msgsnd */
+ case 69: {
+ struct linux_msgsnd_args *p = params;
+ iarg[0] = p->msqid; /* l_int */
+ uarg[1] = (intptr_t) p->msgp; /* struct l_msgbuf * */
+ iarg[2] = p->msgsz; /* l_size_t */
+ iarg[3] = p->msgflg; /* l_int */
+ *n_args = 4;
+ break;
+ }
+ /* linux_msgrcv */
+ case 70: {
+ struct linux_msgrcv_args *p = params;
+ iarg[0] = p->msqid; /* l_int */
+ uarg[1] = (intptr_t) p->msgp; /* struct l_msgbuf * */
+ iarg[2] = p->msgsz; /* l_size_t */
+ iarg[3] = p->msgtyp; /* l_long */
+ iarg[4] = p->msgflg; /* l_int */
+ *n_args = 5;
+ break;
+ }
+ /* linux_msgctl */
+ case 71: {
+ struct linux_msgctl_args *p = params;
+ iarg[0] = p->msqid; /* l_int */
+ iarg[1] = p->cmd; /* l_int */
+ uarg[2] = (intptr_t) p->buf; /* struct l_msqid_ds * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_fcntl */
+ case 72: {
+ struct linux_fcntl_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ iarg[1] = p->cmd; /* l_uint */
+ iarg[2] = p->arg; /* l_ulong */
+ *n_args = 3;
+ break;
+ }
+ /* flock */
+ case 73: {
+ struct flock_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->how; /* int */
+ *n_args = 2;
+ break;
+ }
+ /* fsync */
+ case 74: {
+ struct fsync_args *p = params;
+ iarg[0] = p->fd; /* int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_fdatasync */
+ case 75: {
+ struct linux_fdatasync_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ *n_args = 1;
+ break;
+ }
+ /* linux_truncate */
+ case 76: {
+ struct linux_truncate_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->length; /* l_ulong */
+ *n_args = 2;
+ break;
+ }
+ /* linux_ftruncate */
+ case 77: {
+ struct linux_ftruncate_args *p = params;
+ iarg[0] = p->fd; /* l_int */
+ iarg[1] = p->length; /* l_long */
+ *n_args = 2;
+ break;
+ }
+ /* linux_getdents */
+ case 78: {
+ struct linux_getdents_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ uarg[1] = (intptr_t) p->dent; /* void * */
+ iarg[2] = p->count; /* l_uint */
+ *n_args = 3;
+ break;
+ }
+ /* linux_getcwd */
+ case 79: {
+ struct linux_getcwd_args *p = params;
+ uarg[0] = (intptr_t) p->buf; /* char * */
+ iarg[1] = p->bufsize; /* l_ulong */
+ *n_args = 2;
+ break;
+ }
+ /* linux_chdir */
+ case 80: {
+ struct linux_chdir_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ *n_args = 1;
+ break;
+ }
+ /* fchdir */
+ case 81: {
+ struct fchdir_args *p = params;
+ iarg[0] = p->fd; /* int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_rename */
+ case 82: {
+ struct linux_rename_args *p = params;
+ uarg[0] = (intptr_t) p->from; /* char * */
+ uarg[1] = (intptr_t) p->to; /* char * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_mkdir */
+ case 83: {
+ struct linux_mkdir_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->mode; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_rmdir */
+ case 84: {
+ struct linux_rmdir_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_creat */
+ case 85: {
+ struct linux_creat_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->mode; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_link */
+ case 86: {
+ struct linux_link_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ uarg[1] = (intptr_t) p->to; /* char * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_unlink */
+ case 87: {
+ struct linux_unlink_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_symlink */
+ case 88: {
+ struct linux_symlink_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ uarg[1] = (intptr_t) p->to; /* char * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_readlink */
+ case 89: {
+ struct linux_readlink_args *p = params;
+ uarg[0] = (intptr_t) p->name; /* char * */
+ uarg[1] = (intptr_t) p->buf; /* char * */
+ iarg[2] = p->count; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_chmod */
+ case 90: {
+ struct linux_chmod_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->mode; /* l_mode_t */
+ *n_args = 2;
+ break;
+ }
+ /* fchmod */
+ case 91: {
+ struct fchmod_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->mode; /* int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_chown */
+ case 92: {
+ struct linux_chown_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->uid; /* l_uid_t */
+ iarg[2] = p->gid; /* l_gid_t */
+ *n_args = 3;
+ break;
+ }
+ /* fchown */
+ case 93: {
+ struct fchown_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->uid; /* int */
+ iarg[2] = p->gid; /* int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_lchown */
+ case 94: {
+ struct linux_lchown_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->uid; /* l_uid_t */
+ iarg[2] = p->gid; /* l_gid_t */
+ *n_args = 3;
+ break;
+ }
+ /* umask */
+ case 95: {
+ struct umask_args *p = params;
+ iarg[0] = p->newmask; /* int */
+ *n_args = 1;
+ break;
+ }
+ /* gettimeofday */
+ case 96: {
+ struct gettimeofday_args *p = params;
+ uarg[0] = (intptr_t) p->tp; /* struct l_timeval * */
+ uarg[1] = (intptr_t) p->tzp; /* struct timezone * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_getrlimit */
+ case 97: {
+ struct linux_getrlimit_args *p = params;
+ iarg[0] = p->resource; /* l_uint */
+ uarg[1] = (intptr_t) p->rlim; /* struct l_rlimit * */
+ *n_args = 2;
+ break;
+ }
+ /* getrusage */
+ case 98: {
+ struct getrusage_args *p = params;
+ iarg[0] = p->who; /* int */
+ uarg[1] = (intptr_t) p->rusage; /* struct rusage * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_sysinfo */
+ case 99: {
+ struct linux_sysinfo_args *p = params;
+ uarg[0] = (intptr_t) p->info; /* struct l_sysinfo * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_times */
+ case 100: {
+ struct linux_times_args *p = params;
+ uarg[0] = (intptr_t) p->buf; /* struct l_times_argv * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_ptrace */
+ case 101: {
+ struct linux_ptrace_args *p = params;
+ iarg[0] = p->req; /* l_long */
+ iarg[1] = p->pid; /* l_long */
+ iarg[2] = p->addr; /* l_long */
+ iarg[3] = p->data; /* l_long */
+ *n_args = 4;
+ break;
+ }
+ /* linux_getuid */
+ case 102: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_syslog */
+ case 103: {
+ struct linux_syslog_args *p = params;
+ iarg[0] = p->type; /* l_int */
+ uarg[1] = (intptr_t) p->buf; /* char * */
+ iarg[2] = p->len; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_getgid */
+ case 104: {
+ *n_args = 0;
+ break;
+ }
+ /* setuid */
+ case 105: {
+ struct setuid_args *p = params;
+ uarg[0] = p->uid; /* uid_t */
+ *n_args = 1;
+ break;
+ }
+ /* setgid */
+ case 106: {
+ struct setgid_args *p = params;
+ iarg[0] = p->gid; /* gid_t */
+ *n_args = 1;
+ break;
+ }
+ /* geteuid */
+ case 107: {
+ *n_args = 0;
+ break;
+ }
+ /* getegid */
+ case 108: {
+ *n_args = 0;
+ break;
+ }
+ /* setpgid */
+ case 109: {
+ struct setpgid_args *p = params;
+ iarg[0] = p->pid; /* int */
+ iarg[1] = p->pgid; /* int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_getppid */
+ case 110: {
+ *n_args = 0;
+ break;
+ }
+ /* getpgrp */
+ case 111: {
+ *n_args = 0;
+ break;
+ }
+ /* setsid */
+ case 112: {
+ *n_args = 0;
+ break;
+ }
+ /* setreuid */
+ case 113: {
+ struct setreuid_args *p = params;
+ uarg[0] = p->ruid; /* uid_t */
+ uarg[1] = p->euid; /* uid_t */
+ *n_args = 2;
+ break;
+ }
+ /* setregid */
+ case 114: {
+ struct setregid_args *p = params;
+ iarg[0] = p->rgid; /* gid_t */
+ iarg[1] = p->egid; /* gid_t */
+ *n_args = 2;
+ break;
+ }
+ /* linux_getgroups */
+ case 115: {
+ struct linux_getgroups_args *p = params;
+ iarg[0] = p->gidsetsize; /* l_int */
+ uarg[1] = (intptr_t) p->grouplist; /* l_gid_t * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_setgroups */
+ case 116: {
+ struct linux_setgroups_args *p = params;
+ iarg[0] = p->gidsetsize; /* l_int */
+ uarg[1] = (intptr_t) p->grouplist; /* l_gid_t * */
+ *n_args = 2;
+ break;
+ }
+ /* setresuid */
+ case 117: {
+ struct setresuid_args *p = params;
+ uarg[0] = p->ruid; /* uid_t */
+ uarg[1] = p->euid; /* uid_t */
+ uarg[2] = p->suid; /* uid_t */
+ *n_args = 3;
+ break;
+ }
+ /* getresuid */
+ case 118: {
+ struct getresuid_args *p = params;
+ uarg[0] = (intptr_t) p->ruid; /* uid_t * */
+ uarg[1] = (intptr_t) p->euid; /* uid_t * */
+ uarg[2] = (intptr_t) p->suid; /* uid_t * */
+ *n_args = 3;
+ break;
+ }
+ /* setresgid */
+ case 119: {
+ struct setresgid_args *p = params;
+ iarg[0] = p->rgid; /* gid_t */
+ iarg[1] = p->egid; /* gid_t */
+ iarg[2] = p->sgid; /* gid_t */
+ *n_args = 3;
+ break;
+ }
+ /* getresgid */
+ case 120: {
+ struct getresgid_args *p = params;
+ uarg[0] = (intptr_t) p->rgid; /* gid_t * */
+ uarg[1] = (intptr_t) p->egid; /* gid_t * */
+ uarg[2] = (intptr_t) p->sgid; /* gid_t * */
+ *n_args = 3;
+ break;
+ }
+ /* getpgid */
+ case 121: {
+ struct getpgid_args *p = params;
+ iarg[0] = p->pid; /* int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_setfsuid */
+ case 122: {
+ struct linux_setfsuid_args *p = params;
+ iarg[0] = p->uid; /* l_uid_t */
+ *n_args = 1;
+ break;
+ }
+ /* linux_setfsgid */
+ case 123: {
+ struct linux_setfsgid_args *p = params;
+ iarg[0] = p->gid; /* l_gid_t */
+ *n_args = 1;
+ break;
+ }
+ /* linux_getsid */
+ case 124: {
+ struct linux_getsid_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ *n_args = 1;
+ break;
+ }
+ /* linux_capget */
+ case 125: {
+ struct linux_capget_args *p = params;
+ uarg[0] = (intptr_t) p->hdrp; /* struct l_user_cap_header * */
+ uarg[1] = (intptr_t) p->datap; /* struct l_user_cap_data * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_capset */
+ case 126: {
+ struct linux_capset_args *p = params;
+ uarg[0] = (intptr_t) p->hdrp; /* struct l_user_cap_header * */
+ uarg[1] = (intptr_t) p->datap; /* struct l_user_cap_data * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_rt_sigpending */
+ case 127: {
+ struct linux_rt_sigpending_args *p = params;
+ uarg[0] = (intptr_t) p->set; /* l_sigset_t * */
+ iarg[1] = p->sigsetsize; /* l_size_t */
+ *n_args = 2;
+ break;
+ }
+ /* linux_rt_sigtimedwait */
+ case 128: {
+ struct linux_rt_sigtimedwait_args *p = params;
+ uarg[0] = (intptr_t) p->mask; /* l_sigset_t * */
+ uarg[1] = (intptr_t) p->ptr; /* l_siginfo_t * */
+ uarg[2] = (intptr_t) p->timeout; /* struct l_timeval * */
+ iarg[3] = p->sigsetsize; /* l_size_t */
+ *n_args = 4;
+ break;
+ }
+ /* linux_rt_sigqueueinfo */
+ case 129: {
+ struct linux_rt_sigqueueinfo_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->sig; /* l_int */
+ uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_rt_sigsuspend */
+ case 130: {
+ struct linux_rt_sigsuspend_args *p = params;
+ uarg[0] = (intptr_t) p->newset; /* l_sigset_t * */
+ iarg[1] = p->sigsetsize; /* l_size_t */
+ *n_args = 2;
+ break;
+ }
+ /* linux_sigaltstack */
+ case 131: {
+ struct linux_sigaltstack_args *p = params;
+ uarg[0] = (intptr_t) p->uss; /* l_stack_t * */
+ uarg[1] = (intptr_t) p->uoss; /* l_stack_t * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_utime */
+ case 132: {
+ struct linux_utime_args *p = params;
+ uarg[0] = (intptr_t) p->fname; /* char * */
+ uarg[1] = (intptr_t) p->times; /* struct l_utimbuf * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_mknod */
+ case 133: {
+ struct linux_mknod_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->mode; /* l_int */
+ iarg[2] = p->dev; /* l_dev_t */
+ *n_args = 3;
+ break;
+ }
+ /* linux_personality */
+ case 135: {
+ struct linux_personality_args *p = params;
+ iarg[0] = p->per; /* l_ulong */
+ *n_args = 1;
+ break;
+ }
+ /* linux_ustat */
+ case 136: {
+ struct linux_ustat_args *p = params;
+ iarg[0] = p->dev; /* l_dev_t */
+ uarg[1] = (intptr_t) p->ubuf; /* struct l_ustat * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_statfs */
+ case 137: {
+ struct linux_statfs_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ uarg[1] = (intptr_t) p->buf; /* struct l_statfs_buf * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_fstatfs */
+ case 138: {
+ struct linux_fstatfs_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ uarg[1] = (intptr_t) p->buf; /* struct l_statfs_buf * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_sysfs */
+ case 139: {
+ struct linux_sysfs_args *p = params;
+ iarg[0] = p->option; /* l_int */
+ iarg[1] = p->arg1; /* l_ulong */
+ iarg[2] = p->arg2; /* l_ulong */
+ *n_args = 3;
+ break;
+ }
+ /* linux_getpriority */
+ case 140: {
+ struct linux_getpriority_args *p = params;
+ iarg[0] = p->which; /* int */
+ iarg[1] = p->who; /* int */
+ *n_args = 2;
+ break;
+ }
+ /* setpriority */
+ case 141: {
+ struct setpriority_args *p = params;
+ iarg[0] = p->which; /* int */
+ iarg[1] = p->who; /* int */
+ iarg[2] = p->prio; /* int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_sched_setparam */
+ case 142: {
+ struct linux_sched_setparam_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_sched_getparam */
+ case 143: {
+ struct linux_sched_getparam_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_sched_setscheduler */
+ case 144: {
+ struct linux_sched_setscheduler_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->policy; /* l_int */
+ uarg[2] = (intptr_t) p->param; /* struct l_sched_param * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_sched_getscheduler */
+ case 145: {
+ struct linux_sched_getscheduler_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ *n_args = 1;
+ break;
+ }
+ /* linux_sched_get_priority_max */
+ case 146: {
+ struct linux_sched_get_priority_max_args *p = params;
+ iarg[0] = p->policy; /* l_int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_sched_get_priority_min */
+ case 147: {
+ struct linux_sched_get_priority_min_args *p = params;
+ iarg[0] = p->policy; /* l_int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_sched_rr_get_interval */
+ case 148: {
+ struct linux_sched_rr_get_interval_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ uarg[1] = (intptr_t) p->interval; /* struct l_timespec * */
+ *n_args = 2;
+ break;
+ }
+ /* mlock */
+ case 149: {
+ struct mlock_args *p = params;
+ uarg[0] = (intptr_t) p->addr; /* const void * */
+ uarg[1] = p->len; /* size_t */
+ *n_args = 2;
+ break;
+ }
+ /* munlock */
+ case 150: {
+ struct munlock_args *p = params;
+ uarg[0] = (intptr_t) p->addr; /* const void * */
+ uarg[1] = p->len; /* size_t */
+ *n_args = 2;
+ break;
+ }
+ /* mlockall */
+ case 151: {
+ struct mlockall_args *p = params;
+ iarg[0] = p->how; /* int */
+ *n_args = 1;
+ break;
+ }
+ /* munlockall */
+ case 152: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_vhangup */
+ case 153: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_pivot_root */
+ case 155: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_sysctl */
+ case 156: {
+ struct linux_sysctl_args *p = params;
+ uarg[0] = (intptr_t) p->args; /* struct l___sysctl_args * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_prctl */
+ case 157: {
+ struct linux_prctl_args *p = params;
+ iarg[0] = p->option; /* l_int */
+ iarg[1] = p->arg2; /* l_uintptr_t */
+ iarg[2] = p->arg3; /* l_uintptr_t */
+ iarg[3] = p->arg4; /* l_uintptr_t */
+ iarg[4] = p->arg5; /* l_uintptr_t */
+ *n_args = 5;
+ break;
+ }
+ /* linux_arch_prctl */
+ case 158: {
+ struct linux_arch_prctl_args *p = params;
+ iarg[0] = p->code; /* l_int */
+ iarg[1] = p->addr; /* l_ulong */
+ *n_args = 2;
+ break;
+ }
+ /* linux_adjtimex */
+ case 159: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_setrlimit */
+ case 160: {
+ struct linux_setrlimit_args *p = params;
+ iarg[0] = p->resource; /* l_uint */
+ uarg[1] = (intptr_t) p->rlim; /* struct l_rlimit * */
+ *n_args = 2;
+ break;
+ }
+ /* chroot */
+ case 161: {
+ struct chroot_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ *n_args = 1;
+ break;
+ }
+ /* sync */
+ case 162: {
+ *n_args = 0;
+ break;
+ }
+ /* acct */
+ case 163: {
+ struct acct_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ *n_args = 1;
+ break;
+ }
+ /* settimeofday */
+ case 164: {
+ struct settimeofday_args *p = params;
+ uarg[0] = (intptr_t) p->tp; /* struct l_timeval * */
+ uarg[1] = (intptr_t) p->tzp; /* struct timezone * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_mount */
+ case 165: {
+ struct linux_mount_args *p = params;
+ uarg[0] = (intptr_t) p->specialfile; /* char * */
+ uarg[1] = (intptr_t) p->dir; /* char * */
+ uarg[2] = (intptr_t) p->filesystemtype; /* char * */
+ iarg[3] = p->rwflag; /* l_ulong */
+ uarg[4] = (intptr_t) p->data; /* void * */
+ *n_args = 5;
+ break;
+ }
+ /* linux_umount */
+ case 166: {
+ struct linux_umount_args *p = params;
+ uarg[0] = (intptr_t) p->path; /* char * */
+ iarg[1] = p->flags; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* swapon */
+ case 167: {
+ struct swapon_args *p = params;
+ uarg[0] = (intptr_t) p->name; /* char * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_swapoff */
+ case 168: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_reboot */
+ case 169: {
+ struct linux_reboot_args *p = params;
+ iarg[0] = p->magic1; /* l_int */
+ iarg[1] = p->magic2; /* l_int */
+ iarg[2] = p->cmd; /* l_uint */
+ uarg[3] = (intptr_t) p->arg; /* void * */
+ *n_args = 4;
+ break;
+ }
+ /* linux_sethostname */
+ case 170: {
+ struct linux_sethostname_args *p = params;
+ uarg[0] = (intptr_t) p->hostname; /* char * */
+ iarg[1] = p->len; /* l_uint */
+ *n_args = 2;
+ break;
+ }
+ /* linux_setdomainname */
+ case 171: {
+ struct linux_setdomainname_args *p = params;
+ uarg[0] = (intptr_t) p->name; /* char * */
+ iarg[1] = p->len; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_iopl */
+ case 172: {
+ struct linux_iopl_args *p = params;
+ iarg[0] = p->level; /* l_uint */
+ *n_args = 1;
+ break;
+ }
+ /* linux_create_module */
+ case 174: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_init_module */
+ case 175: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_delete_module */
+ case 176: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_get_kernel_syms */
+ case 177: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_query_module */
+ case 178: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_quotactl */
+ case 179: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_nfsservctl */
+ case 180: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_getpmsg */
+ case 181: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_putpmsg */
+ case 182: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_afs_syscall */
+ case 183: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_tuxcall */
+ case 184: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_security */
+ case 185: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_gettid */
+ case 186: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_setxattr */
+ case 188: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_lsetxattr */
+ case 189: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_fsetxattr */
+ case 190: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_getxattr */
+ case 191: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_lgetxattr */
+ case 192: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_fgetxattr */
+ case 193: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_listxattr */
+ case 194: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_llistxattr */
+ case 195: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_flistxattr */
+ case 196: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_removexattr */
+ case 197: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_lremovexattr */
+ case 198: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_fremovexattr */
+ case 199: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_tkill */
+ case 200: {
+ struct linux_tkill_args *p = params;
+ iarg[0] = p->tid; /* int */
+ iarg[1] = p->sig; /* int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_time */
+ case 201: {
+ struct linux_time_args *p = params;
+ uarg[0] = (intptr_t) p->tm; /* l_time_t * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_sys_futex */
+ case 202: {
+ struct linux_sys_futex_args *p = params;
+ uarg[0] = (intptr_t) p->uaddr; /* void * */
+ iarg[1] = p->op; /* int */
+ iarg[2] = p->val; /* int */
+ uarg[3] = (intptr_t) p->timeout; /* struct l_timespec * */
+ uarg[4] = (intptr_t) p->uaddr2; /* void * */
+ iarg[5] = p->val3; /* int */
+ *n_args = 6;
+ break;
+ }
+ /* linux_sched_setaffinity */
+ case 203: {
+ struct linux_sched_setaffinity_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->len; /* l_uint */
+ uarg[2] = (intptr_t) p->user_mask_ptr; /* l_ulong * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_sched_getaffinity */
+ case 204: {
+ struct linux_sched_getaffinity_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->len; /* l_uint */
+ uarg[2] = (intptr_t) p->user_mask_ptr; /* l_ulong * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_set_thread_area */
+ case 205: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_lookup_dcookie */
+ case 212: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_epoll_create */
+ case 213: {
+ struct linux_epoll_create_args *p = params;
+ iarg[0] = p->size; /* l_int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_epoll_ctl_old */
+ case 214: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_epoll_wait_old */
+ case 215: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_remap_file_pages */
+ case 216: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_getdents64 */
+ case 217: {
+ struct linux_getdents64_args *p = params;
+ iarg[0] = p->fd; /* l_uint */
+ uarg[1] = (intptr_t) p->dirent; /* void * */
+ iarg[2] = p->count; /* l_uint */
+ *n_args = 3;
+ break;
+ }
+ /* linux_set_tid_address */
+ case 218: {
+ struct linux_set_tid_address_args *p = params;
+ uarg[0] = (intptr_t) p->tidptr; /* int * */
+ *n_args = 1;
+ break;
+ }
+ /* linux_semtimedop */
+ case 220: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_fadvise64 */
+ case 221: {
+ struct linux_fadvise64_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->offset; /* l_loff_t */
+ iarg[2] = p->len; /* l_size_t */
+ iarg[3] = p->advice; /* int */
+ *n_args = 4;
+ break;
+ }
+ /* linux_timer_create */
+ case 222: {
+ struct linux_timer_create_args *p = params;
+ iarg[0] = p->clock_id; /* clockid_t */
+ uarg[1] = (intptr_t) p->evp; /* struct sigevent * */
+ uarg[2] = (intptr_t) p->timerid; /* l_timer_t * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_timer_settime */
+ case 223: {
+ struct linux_timer_settime_args *p = params;
+ iarg[0] = p->timerid; /* l_timer_t */
+ iarg[1] = p->flags; /* l_int */
+ uarg[2] = (intptr_t) p->new; /* const struct itimerspec * */
+ uarg[3] = (intptr_t) p->old; /* struct itimerspec * */
+ *n_args = 4;
+ break;
+ }
+ /* linux_timer_gettime */
+ case 224: {
+ struct linux_timer_gettime_args *p = params;
+ iarg[0] = p->timerid; /* l_timer_t */
+ uarg[1] = (intptr_t) p->setting; /* struct itimerspec * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_timer_getoverrun */
+ case 225: {
+ struct linux_timer_getoverrun_args *p = params;
+ iarg[0] = p->timerid; /* l_timer_t */
+ *n_args = 1;
+ break;
+ }
+ /* linux_timer_delete */
+ case 226: {
+ struct linux_timer_delete_args *p = params;
+ iarg[0] = p->timerid; /* l_timer_t */
+ *n_args = 1;
+ break;
+ }
+ /* linux_clock_settime */
+ case 227: {
+ struct linux_clock_settime_args *p = params;
+ iarg[0] = p->which; /* clockid_t */
+ uarg[1] = (intptr_t) p->tp; /* struct l_timespec * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_clock_gettime */
+ case 228: {
+ struct linux_clock_gettime_args *p = params;
+ iarg[0] = p->which; /* clockid_t */
+ uarg[1] = (intptr_t) p->tp; /* struct l_timespec * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_clock_getres */
+ case 229: {
+ struct linux_clock_getres_args *p = params;
+ iarg[0] = p->which; /* clockid_t */
+ uarg[1] = (intptr_t) p->tp; /* struct l_timespec * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_clock_nanosleep */
+ case 230: {
+ struct linux_clock_nanosleep_args *p = params;
+ iarg[0] = p->which; /* clockid_t */
+ iarg[1] = p->flags; /* int */
+ uarg[2] = (intptr_t) p->rqtp; /* struct l_timespec * */
+ uarg[3] = (intptr_t) p->rmtp; /* struct l_timespec * */
+ *n_args = 4;
+ break;
+ }
+ /* linux_exit_group */
+ case 231: {
+ struct linux_exit_group_args *p = params;
+ iarg[0] = p->error_code; /* int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_epoll_wait */
+ case 232: {
+ struct linux_epoll_wait_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ uarg[1] = (intptr_t) p->events; /* struct epoll_event * */
+ iarg[2] = p->maxevents; /* l_int */
+ iarg[3] = p->timeout; /* l_int */
+ *n_args = 4;
+ break;
+ }
+ /* linux_epoll_ctl */
+ case 233: {
+ struct linux_epoll_ctl_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ iarg[1] = p->op; /* l_int */
+ iarg[2] = p->fd; /* l_int */
+ uarg[3] = (intptr_t) p->event; /* struct epoll_event * */
+ *n_args = 4;
+ break;
+ }
+ /* linux_tgkill */
+ case 234: {
+ struct linux_tgkill_args *p = params;
+ iarg[0] = p->tgid; /* int */
+ iarg[1] = p->pid; /* int */
+ iarg[2] = p->sig; /* int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_utimes */
+ case 235: {
+ struct linux_utimes_args *p = params;
+ uarg[0] = (intptr_t) p->fname; /* char * */
+ uarg[1] = (intptr_t) p->tptr; /* struct l_timeval * */
+ *n_args = 2;
+ break;
+ }
+ /* linux_mbind */
+ case 237: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_set_mempolicy */
+ case 238: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_get_mempolicy */
+ case 239: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_mq_open */
+ case 240: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_mq_unlink */
+ case 241: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_mq_timedsend */
+ case 242: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_mq_timedreceive */
+ case 243: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_mq_notify */
+ case 244: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_mq_getsetattr */
+ case 245: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_kexec_load */
+ case 246: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_waitid */
+ case 247: {
+ struct linux_waitid_args *p = params;
+ iarg[0] = p->idtype; /* int */
+ iarg[1] = p->id; /* l_pid_t */
+ uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */
+ iarg[3] = p->options; /* int */
+ uarg[4] = (intptr_t) p->rusage; /* struct rusage * */
+ *n_args = 5;
+ break;
+ }
+ /* linux_add_key */
+ case 248: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_request_key */
+ case 249: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_keyctl */
+ case 250: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_ioprio_set */
+ case 251: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_ioprio_get */
+ case 252: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_inotify_init */
+ case 253: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_inotify_add_watch */
+ case 254: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_inotify_rm_watch */
+ case 255: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_migrate_pages */
+ case 256: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_openat */
+ case 257: {
+ struct linux_openat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->filename; /* const char * */
+ iarg[2] = p->flags; /* l_int */
+ iarg[3] = p->mode; /* l_int */
+ *n_args = 4;
+ break;
+ }
+ /* linux_mkdirat */
+ case 258: {
+ struct linux_mkdirat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->pathname; /* const char * */
+ iarg[2] = p->mode; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_mknodat */
+ case 259: {
+ struct linux_mknodat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->filename; /* const char * */
+ iarg[2] = p->mode; /* l_int */
+ iarg[3] = p->dev; /* l_uint */
+ *n_args = 4;
+ break;
+ }
+ /* linux_fchownat */
+ case 260: {
+ struct linux_fchownat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->filename; /* const char * */
+ iarg[2] = p->uid; /* l_uid_t */
+ iarg[3] = p->gid; /* l_gid_t */
+ iarg[4] = p->flag; /* l_int */
+ *n_args = 5;
+ break;
+ }
+ /* linux_futimesat */
+ case 261: {
+ struct linux_futimesat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->filename; /* char * */
+ uarg[2] = (intptr_t) p->utimes; /* struct l_timeval * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_newfstatat */
+ case 262: {
+ struct linux_newfstatat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->pathname; /* char * */
+ uarg[2] = (intptr_t) p->statbuf; /* struct l_stat64 * */
+ iarg[3] = p->flag; /* l_int */
+ *n_args = 4;
+ break;
+ }
+ /* linux_unlinkat */
+ case 263: {
+ struct linux_unlinkat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->pathname; /* const char * */
+ iarg[2] = p->flag; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_renameat */
+ case 264: {
+ struct linux_renameat_args *p = params;
+ iarg[0] = p->olddfd; /* l_int */
+ uarg[1] = (intptr_t) p->oldname; /* const char * */
+ iarg[2] = p->newdfd; /* l_int */
+ uarg[3] = (intptr_t) p->newname; /* const char * */
+ *n_args = 4;
+ break;
+ }
+ /* linux_linkat */
+ case 265: {
+ struct linux_linkat_args *p = params;
+ iarg[0] = p->olddfd; /* l_int */
+ uarg[1] = (intptr_t) p->oldname; /* const char * */
+ iarg[2] = p->newdfd; /* l_int */
+ uarg[3] = (intptr_t) p->newname; /* const char * */
+ iarg[4] = p->flag; /* l_int */
+ *n_args = 5;
+ break;
+ }
+ /* linux_symlinkat */
+ case 266: {
+ struct linux_symlinkat_args *p = params;
+ uarg[0] = (intptr_t) p->oldname; /* const char * */
+ iarg[1] = p->newdfd; /* l_int */
+ uarg[2] = (intptr_t) p->newname; /* const char * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_readlinkat */
+ case 267: {
+ struct linux_readlinkat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->path; /* const char * */
+ uarg[2] = (intptr_t) p->buf; /* char * */
+ iarg[3] = p->bufsiz; /* l_int */
+ *n_args = 4;
+ break;
+ }
+ /* linux_fchmodat */
+ case 268: {
+ struct linux_fchmodat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->filename; /* const char * */
+ iarg[2] = p->mode; /* l_mode_t */
+ *n_args = 3;
+ break;
+ }
+ /* linux_faccessat */
+ case 269: {
+ struct linux_faccessat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->filename; /* const char * */
+ iarg[2] = p->amode; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_pselect6 */
+ case 270: {
+ struct linux_pselect6_args *p = params;
+ iarg[0] = p->nfds; /* l_int */
+ uarg[1] = (intptr_t) p->readfds; /* l_fd_set * */
+ uarg[2] = (intptr_t) p->writefds; /* l_fd_set * */
+ uarg[3] = (intptr_t) p->exceptfds; /* l_fd_set * */
+ uarg[4] = (intptr_t) p->tsp; /* struct l_timespec * */
+ uarg[5] = (intptr_t) p->sig; /* l_uintptr_t * */
+ *n_args = 6;
+ break;
+ }
+ /* linux_ppoll */
+ case 271: {
+ struct linux_ppoll_args *p = params;
+ uarg[0] = (intptr_t) p->fds; /* struct pollfd * */
+ uarg[1] = p->nfds; /* uint32_t */
+ uarg[2] = (intptr_t) p->tsp; /* struct l_timespec * */
+ uarg[3] = (intptr_t) p->sset; /* l_sigset_t * */
+ iarg[4] = p->ssize; /* l_size_t */
+ *n_args = 5;
+ break;
+ }
+ /* linux_unshare */
+ case 272: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_set_robust_list */
+ case 273: {
+ struct linux_set_robust_list_args *p = params;
+ uarg[0] = (intptr_t) p->head; /* struct linux_robust_list_head * */
+ iarg[1] = p->len; /* l_size_t */
+ *n_args = 2;
+ break;
+ }
+ /* linux_get_robust_list */
+ case 274: {
+ struct linux_get_robust_list_args *p = params;
+ iarg[0] = p->pid; /* l_int */
+ uarg[1] = (intptr_t) p->head; /* struct linux_robust_list_head * */
+ uarg[2] = (intptr_t) p->len; /* l_size_t * */
+ *n_args = 3;
+ break;
+ }
+ /* linux_splice */
+ case 275: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_tee */
+ case 276: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_sync_file_range */
+ case 277: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_vmsplice */
+ case 278: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_move_pages */
+ case 279: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_utimensat */
+ case 280: {
+ struct linux_utimensat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->pathname; /* const char * */
+ uarg[2] = (intptr_t) p->times; /* const struct l_timespec * */
+ iarg[3] = p->flags; /* l_int */
+ *n_args = 4;
+ break;
+ }
+ /* linux_epoll_pwait */
+ case 281: {
+ struct linux_epoll_pwait_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ uarg[1] = (intptr_t) p->events; /* struct epoll_event * */
+ iarg[2] = p->maxevents; /* l_int */
+ iarg[3] = p->timeout; /* l_int */
+ uarg[4] = (intptr_t) p->mask; /* l_sigset_t * */
+ *n_args = 5;
+ break;
+ }
+ /* linux_signalfd */
+ case 282: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_timerfd */
+ case 283: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_eventfd */
+ case 284: {
+ struct linux_eventfd_args *p = params;
+ iarg[0] = p->initval; /* l_uint */
+ *n_args = 1;
+ break;
+ }
+ /* linux_fallocate */
+ case 285: {
+ struct linux_fallocate_args *p = params;
+ iarg[0] = p->fd; /* l_int */
+ iarg[1] = p->mode; /* l_int */
+ iarg[2] = p->offset; /* l_loff_t */
+ iarg[3] = p->len; /* l_loff_t */
+ *n_args = 4;
+ break;
+ }
+ /* linux_timerfd_settime */
+ case 286: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_timerfd_gettime */
+ case 287: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_accept4 */
+ case 288: {
+ struct linux_accept4_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ iarg[1] = p->addr; /* l_uintptr_t */
+ iarg[2] = p->namelen; /* l_uintptr_t */
+ iarg[3] = p->flags; /* int */
+ *n_args = 4;
+ break;
+ }
+ /* linux_signalfd4 */
+ case 289: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_eventfd2 */
+ case 290: {
+ struct linux_eventfd2_args *p = params;
+ iarg[0] = p->initval; /* l_uint */
+ iarg[1] = p->flags; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_epoll_create1 */
+ case 291: {
+ struct linux_epoll_create1_args *p = params;
+ iarg[0] = p->flags; /* l_int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_dup3 */
+ case 292: {
+ struct linux_dup3_args *p = params;
+ iarg[0] = p->oldfd; /* l_int */
+ iarg[1] = p->newfd; /* l_int */
+ iarg[2] = p->flags; /* l_int */
+ *n_args = 3;
+ break;
+ }
+ /* linux_pipe2 */
+ case 293: {
+ struct linux_pipe2_args *p = params;
+ uarg[0] = (intptr_t) p->pipefds; /* l_int * */
+ iarg[1] = p->flags; /* l_int */
+ *n_args = 2;
+ break;
+ }
+ /* linux_inotify_init1 */
+ case 294: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_preadv */
+ case 295: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_pwritev */
+ case 296: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_rt_tsigqueueinfo */
+ case 297: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_perf_event_open */
+ case 298: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_recvmmsg */
+ case 299: {
+ struct linux_recvmmsg_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */
+ iarg[2] = p->vlen; /* l_uint */
+ iarg[3] = p->flags; /* l_uint */
+ uarg[4] = (intptr_t) p->timeout; /* struct l_timespec * */
+ *n_args = 5;
+ break;
+ }
+ /* linux_fanotify_init */
+ case 300: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_fanotify_mark */
+ case 301: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_prlimit64 */
+ case 302: {
+ struct linux_prlimit64_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->resource; /* l_uint */
+ uarg[2] = (intptr_t) p->new; /* struct rlimit * */
+ uarg[3] = (intptr_t) p->old; /* struct rlimit * */
+ *n_args = 4;
+ break;
+ }
+ /* linux_name_to_handle_at */
+ case 303: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_open_by_handle_at */
+ case 304: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_clock_adjtime */
+ case 305: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_syncfs */
+ case 306: {
+ struct linux_syncfs_args *p = params;
+ iarg[0] = p->fd; /* l_int */
+ *n_args = 1;
+ break;
+ }
+ /* linux_sendmmsg */
+ case 307: {
+ struct linux_sendmmsg_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */
+ iarg[2] = p->vlen; /* l_uint */
+ iarg[3] = p->flags; /* l_uint */
+ *n_args = 4;
+ break;
+ }
+ /* linux_setns */
+ case 308: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_process_vm_readv */
+ case 309: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_process_vm_writev */
+ case 310: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_kcmp */
+ case 311: {
+ *n_args = 0;
+ break;
+ }
+ /* linux_finit_module */
+ case 312: {
+ *n_args = 0;
+ break;
+ }
+ default:
+ *n_args = 0;
+ break;
+ };
+}
+static void
+systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
+{
+ const char *p = NULL;
+ switch (sysnum) {
+#define nosys linux_nosys
+ /* read */
+ case 0:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "u_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* write */
+ case 1:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "u_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_open */
+ case 2:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* close */
+ case 3:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_newstat */
+ case 4:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "struct l_newstat *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_newfstat */
+ case 5:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "struct l_newstat *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_newlstat */
+ case 6:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "struct l_newstat *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* poll */
+ case 7:
+ switch(ndx) {
+ case 0:
+ p = "struct pollfd";
+ break;
+ case 1:
+ p = "unsigned int";
+ break;
+ case 2:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_lseek */
+ case 8:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "l_off_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mmap2 */
+ case 9:
+ switch(ndx) {
+ case 0:
+ p = "l_ulong";
+ break;
+ case 1:
+ p = "l_ulong";
+ break;
+ case 2:
+ p = "l_ulong";
+ break;
+ case 3:
+ p = "l_ulong";
+ break;
+ case 4:
+ p = "l_ulong";
+ break;
+ case 5:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mprotect */
+ case 10:
+ switch(ndx) {
+ case 0:
+ p = "caddr_t";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* munmap */
+ case 11:
+ switch(ndx) {
+ case 0:
+ p = "caddr_t";
+ break;
+ case 1:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_brk */
+ case 12:
+ switch(ndx) {
+ case 0:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rt_sigaction */
+ case 13:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_sigaction_t *";
+ break;
+ case 2:
+ p = "l_sigaction_t *";
+ break;
+ case 3:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rt_sigprocmask */
+ case 14:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_sigset_t *";
+ break;
+ case 2:
+ p = "l_sigset_t *";
+ break;
+ case 3:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rt_sigreturn */
+ case 15:
+ switch(ndx) {
+ case 0:
+ p = "struct l_ucontext *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_ioctl */
+ case 16:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "l_uint";
+ break;
+ case 2:
+ p = "uintptr_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_pread */
+ case 17:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "l_size_t";
+ break;
+ case 3:
+ p = "l_loff_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_pwrite */
+ case 18:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "l_size_t";
+ break;
+ case 3:
+ p = "l_loff_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* readv */
+ case 19:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "struct iovec *";
+ break;
+ case 2:
+ p = "u_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* writev */
+ case 20:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "struct iovec *";
+ break;
+ case 2:
+ p = "u_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_access */
+ case 21:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_pipe */
+ case 22:
+ switch(ndx) {
+ case 0:
+ p = "l_ulong *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_select */
+ case 23:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_fd_set *";
+ break;
+ case 2:
+ p = "l_fd_set *";
+ break;
+ case 3:
+ p = "l_fd_set *";
+ break;
+ case 4:
+ p = "struct l_timeval *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* sched_yield */
+ case 24:
+ break;
+ /* linux_mremap */
+ case 25:
+ switch(ndx) {
+ case 0:
+ p = "l_ulong";
+ break;
+ case 1:
+ p = "l_ulong";
+ break;
+ case 2:
+ p = "l_ulong";
+ break;
+ case 3:
+ p = "l_ulong";
+ break;
+ case 4:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_msync */
+ case 26:
+ switch(ndx) {
+ case 0:
+ p = "l_ulong";
+ break;
+ case 1:
+ p = "l_size_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mincore */
+ case 27:
+ switch(ndx) {
+ case 0:
+ p = "l_ulong";
+ break;
+ case 1:
+ p = "l_size_t";
+ break;
+ case 2:
+ p = "u_char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* madvise */
+ case 28:
+ switch(ndx) {
+ case 0:
+ p = "void *";
+ break;
+ case 1:
+ p = "size_t";
+ break;
+ case 2:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_shmget */
+ case 29:
+ switch(ndx) {
+ case 0:
+ p = "l_key_t";
+ break;
+ case 1:
+ p = "l_size_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_shmat */
+ case 30:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_shmctl */
+ case 31:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "struct l_shmid_ds *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* dup */
+ case 32:
+ switch(ndx) {
+ case 0:
+ p = "u_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* dup2 */
+ case 33:
+ switch(ndx) {
+ case 0:
+ p = "u_int";
+ break;
+ case 1:
+ p = "u_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_pause */
+ case 34:
+ break;
+ /* linux_nanosleep */
+ case 35:
+ switch(ndx) {
+ case 0:
+ p = "const struct l_timespec *";
+ break;
+ case 1:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getitimer */
+ case 36:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_itimerval *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_alarm */
+ case 37:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_setitimer */
+ case 38:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_itimerval *";
+ break;
+ case 2:
+ p = "struct l_itimerval *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getpid */
+ case 39:
+ break;
+ /* linux_sendfile */
+ case 40:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "l_long *";
+ break;
+ case 3:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_socket */
+ case 41:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_connect */
+ case 42:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_accept */
+ case 43:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_uintptr_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sendto */
+ case 44:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ case 4:
+ p = "l_uintptr_t";
+ break;
+ case 5:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_recvfrom */
+ case 45:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_size_t";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ case 4:
+ p = "l_uintptr_t";
+ break;
+ case 5:
+ p = "l_uintptr_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sendmsg */
+ case 46:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_recvmsg */
+ case 47:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_shutdown */
+ case 48:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_bind */
+ case 49:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_listen */
+ case 50:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getsockname */
+ case 51:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_uintptr_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getpeername */
+ case 52:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_uintptr_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_socketpair */
+ case 53:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_uintptr_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_setsockopt */
+ case 54:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_uintptr_t";
+ break;
+ case 4:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getsockopt */
+ case 55:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_uintptr_t";
+ break;
+ case 4:
+ p = "l_uintptr_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_clone */
+ case 56:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "void *";
+ break;
+ case 2:
+ p = "void *";
+ break;
+ case 3:
+ p = "void *";
+ break;
+ case 4:
+ p = "void *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_fork */
+ case 57:
+ break;
+ /* linux_vfork */
+ case 58:
+ break;
+ /* linux_execve */
+ case 59:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "char **";
+ break;
+ case 2:
+ p = "char **";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_exit */
+ case 60:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_wait4 */
+ case 61:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_int *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "struct rusage *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_kill */
+ case 62:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_newuname */
+ case 63:
+ switch(ndx) {
+ case 0:
+ p = "struct l_new_utsname *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_semget */
+ case 64:
+ switch(ndx) {
+ case 0:
+ p = "l_key_t";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_semop */
+ case 65:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_sembuf *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_semctl */
+ case 66:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "union l_semun";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_shmdt */
+ case 67:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_msgget */
+ case 68:
+ switch(ndx) {
+ case 0:
+ p = "l_key_t";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_msgsnd */
+ case 69:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_msgbuf *";
+ break;
+ case 2:
+ p = "l_size_t";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_msgrcv */
+ case 70:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_msgbuf *";
+ break;
+ case 2:
+ p = "l_size_t";
+ break;
+ case 3:
+ p = "l_long";
+ break;
+ case 4:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_msgctl */
+ case 71:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "struct l_msqid_ds *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_fcntl */
+ case 72:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "l_uint";
+ break;
+ case 2:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* flock */
+ case 73:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* fsync */
+ case 74:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_fdatasync */
+ case 75:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_truncate */
+ case 76:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_ftruncate */
+ case 77:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_long";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getdents */
+ case 78:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "void *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getcwd */
+ case 79:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_chdir */
+ case 80:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* fchdir */
+ case 81:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rename */
+ case 82:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mkdir */
+ case 83:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rmdir */
+ case 84:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_creat */
+ case 85:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_link */
+ case 86:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_unlink */
+ case 87:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_symlink */
+ case 88:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_readlink */
+ case 89:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_chmod */
+ case 90:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_mode_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* fchmod */
+ case 91:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_chown */
+ case 92:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_uid_t";
+ break;
+ case 2:
+ p = "l_gid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* fchown */
+ case 93:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_lchown */
+ case 94:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_uid_t";
+ break;
+ case 2:
+ p = "l_gid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* umask */
+ case 95:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* gettimeofday */
+ case 96:
+ switch(ndx) {
+ case 0:
+ p = "struct l_timeval *";
+ break;
+ case 1:
+ p = "struct timezone *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getrlimit */
+ case 97:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "struct l_rlimit *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* getrusage */
+ case 98:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "struct rusage *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sysinfo */
+ case 99:
+ switch(ndx) {
+ case 0:
+ p = "struct l_sysinfo *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_times */
+ case 100:
+ switch(ndx) {
+ case 0:
+ p = "struct l_times_argv *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_ptrace */
+ case 101:
+ switch(ndx) {
+ case 0:
+ p = "l_long";
+ break;
+ case 1:
+ p = "l_long";
+ break;
+ case 2:
+ p = "l_long";
+ break;
+ case 3:
+ p = "l_long";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getuid */
+ case 102:
+ break;
+ /* linux_syslog */
+ case 103:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getgid */
+ case 104:
+ break;
+ /* setuid */
+ case 105:
+ switch(ndx) {
+ case 0:
+ p = "uid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* setgid */
+ case 106:
+ switch(ndx) {
+ case 0:
+ p = "gid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* geteuid */
+ case 107:
+ break;
+ /* getegid */
+ case 108:
+ break;
+ /* setpgid */
+ case 109:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getppid */
+ case 110:
+ break;
+ /* getpgrp */
+ case 111:
+ break;
+ /* setsid */
+ case 112:
+ break;
+ /* setreuid */
+ case 113:
+ switch(ndx) {
+ case 0:
+ p = "uid_t";
+ break;
+ case 1:
+ p = "uid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* setregid */
+ case 114:
+ switch(ndx) {
+ case 0:
+ p = "gid_t";
+ break;
+ case 1:
+ p = "gid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getgroups */
+ case 115:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_gid_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_setgroups */
+ case 116:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_gid_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* setresuid */
+ case 117:
+ switch(ndx) {
+ case 0:
+ p = "uid_t";
+ break;
+ case 1:
+ p = "uid_t";
+ break;
+ case 2:
+ p = "uid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* getresuid */
+ case 118:
+ switch(ndx) {
+ case 0:
+ p = "uid_t *";
+ break;
+ case 1:
+ p = "uid_t *";
+ break;
+ case 2:
+ p = "uid_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* setresgid */
+ case 119:
+ switch(ndx) {
+ case 0:
+ p = "gid_t";
+ break;
+ case 1:
+ p = "gid_t";
+ break;
+ case 2:
+ p = "gid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* getresgid */
+ case 120:
+ switch(ndx) {
+ case 0:
+ p = "gid_t *";
+ break;
+ case 1:
+ p = "gid_t *";
+ break;
+ case 2:
+ p = "gid_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* getpgid */
+ case 121:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_setfsuid */
+ case 122:
+ switch(ndx) {
+ case 0:
+ p = "l_uid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_setfsgid */
+ case 123:
+ switch(ndx) {
+ case 0:
+ p = "l_gid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getsid */
+ case 124:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_capget */
+ case 125:
+ switch(ndx) {
+ case 0:
+ p = "struct l_user_cap_header *";
+ break;
+ case 1:
+ p = "struct l_user_cap_data *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_capset */
+ case 126:
+ switch(ndx) {
+ case 0:
+ p = "struct l_user_cap_header *";
+ break;
+ case 1:
+ p = "struct l_user_cap_data *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rt_sigpending */
+ case 127:
+ switch(ndx) {
+ case 0:
+ p = "l_sigset_t *";
+ break;
+ case 1:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rt_sigtimedwait */
+ case 128:
+ switch(ndx) {
+ case 0:
+ p = "l_sigset_t *";
+ break;
+ case 1:
+ p = "l_siginfo_t *";
+ break;
+ case 2:
+ p = "struct l_timeval *";
+ break;
+ case 3:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rt_sigqueueinfo */
+ case 129:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_siginfo_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_rt_sigsuspend */
+ case 130:
+ switch(ndx) {
+ case 0:
+ p = "l_sigset_t *";
+ break;
+ case 1:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sigaltstack */
+ case 131:
+ switch(ndx) {
+ case 0:
+ p = "l_stack_t *";
+ break;
+ case 1:
+ p = "l_stack_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_utime */
+ case 132:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "struct l_utimbuf *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mknod */
+ case 133:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_dev_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_personality */
+ case 135:
+ switch(ndx) {
+ case 0:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_ustat */
+ case 136:
+ switch(ndx) {
+ case 0:
+ p = "l_dev_t";
+ break;
+ case 1:
+ p = "struct l_ustat *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_statfs */
+ case 137:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "struct l_statfs_buf *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_fstatfs */
+ case 138:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "struct l_statfs_buf *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sysfs */
+ case 139:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_ulong";
+ break;
+ case 2:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_getpriority */
+ case 140:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* setpriority */
+ case 141:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_setparam */
+ case 142:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "struct l_sched_param *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_getparam */
+ case 143:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "struct l_sched_param *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_setscheduler */
+ case 144:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "struct l_sched_param *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_getscheduler */
+ case 145:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_get_priority_max */
+ case 146:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_get_priority_min */
+ case 147:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_rr_get_interval */
+ case 148:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* mlock */
+ case 149:
+ switch(ndx) {
+ case 0:
+ p = "const void *";
+ break;
+ case 1:
+ p = "size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* munlock */
+ case 150:
+ switch(ndx) {
+ case 0:
+ p = "const void *";
+ break;
+ case 1:
+ p = "size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* mlockall */
+ case 151:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* munlockall */
+ case 152:
+ break;
+ /* linux_vhangup */
+ case 153:
+ break;
+ /* linux_pivot_root */
+ case 155:
+ break;
+ /* linux_sysctl */
+ case 156:
+ switch(ndx) {
+ case 0:
+ p = "struct l___sysctl_args *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_prctl */
+ case 157:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_uintptr_t";
+ break;
+ case 3:
+ p = "l_uintptr_t";
+ break;
+ case 4:
+ p = "l_uintptr_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_arch_prctl */
+ case 158:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_ulong";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_adjtimex */
+ case 159:
+ break;
+ /* linux_setrlimit */
+ case 160:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "struct l_rlimit *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* chroot */
+ case 161:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* sync */
+ case 162:
+ break;
+ /* acct */
+ case 163:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* settimeofday */
+ case 164:
+ switch(ndx) {
+ case 0:
+ p = "struct l_timeval *";
+ break;
+ case 1:
+ p = "struct timezone *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mount */
+ case 165:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "char *";
+ break;
+ case 3:
+ p = "l_ulong";
+ break;
+ case 4:
+ p = "void *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_umount */
+ case 166:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* swapon */
+ case 167:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_swapoff */
+ case 168:
+ break;
+ /* linux_reboot */
+ case 169:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ case 3:
+ p = "void *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sethostname */
+ case 170:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_setdomainname */
+ case 171:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_iopl */
+ case 172:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_create_module */
+ case 174:
+ break;
+ /* linux_init_module */
+ case 175:
+ break;
+ /* linux_delete_module */
+ case 176:
+ break;
+ /* linux_get_kernel_syms */
+ case 177:
+ break;
+ /* linux_query_module */
+ case 178:
+ break;
+ /* linux_quotactl */
+ case 179:
+ break;
+ /* linux_nfsservctl */
+ case 180:
+ break;
+ /* linux_getpmsg */
+ case 181:
+ break;
+ /* linux_putpmsg */
+ case 182:
+ break;
+ /* linux_afs_syscall */
+ case 183:
+ break;
+ /* linux_tuxcall */
+ case 184:
+ break;
+ /* linux_security */
+ case 185:
+ break;
+ /* linux_gettid */
+ case 186:
+ break;
+ /* linux_setxattr */
+ case 188:
+ break;
+ /* linux_lsetxattr */
+ case 189:
+ break;
+ /* linux_fsetxattr */
+ case 190:
+ break;
+ /* linux_getxattr */
+ case 191:
+ break;
+ /* linux_lgetxattr */
+ case 192:
+ break;
+ /* linux_fgetxattr */
+ case 193:
+ break;
+ /* linux_listxattr */
+ case 194:
+ break;
+ /* linux_llistxattr */
+ case 195:
+ break;
+ /* linux_flistxattr */
+ case 196:
+ break;
+ /* linux_removexattr */
+ case 197:
+ break;
+ /* linux_lremovexattr */
+ case 198:
+ break;
+ /* linux_fremovexattr */
+ case 199:
+ break;
+ /* linux_tkill */
+ case 200:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_time */
+ case 201:
+ switch(ndx) {
+ case 0:
+ p = "l_time_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sys_futex */
+ case 202:
+ switch(ndx) {
+ case 0:
+ p = "void *";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "int";
+ break;
+ case 3:
+ p = "struct l_timespec *";
+ break;
+ case 4:
+ p = "void *";
+ break;
+ case 5:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_setaffinity */
+ case 203:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_uint";
+ break;
+ case 2:
+ p = "l_ulong *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sched_getaffinity */
+ case 204:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_uint";
+ break;
+ case 2:
+ p = "l_ulong *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_set_thread_area */
+ case 205:
+ break;
+ /* linux_lookup_dcookie */
+ case 212:
+ break;
+ /* linux_epoll_create */
+ case 213:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_epoll_ctl_old */
+ case 214:
+ break;
+ /* linux_epoll_wait_old */
+ case 215:
+ break;
+ /* linux_remap_file_pages */
+ case 216:
+ break;
+ /* linux_getdents64 */
+ case 217:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "void *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_set_tid_address */
+ case 218:
+ switch(ndx) {
+ case 0:
+ p = "int *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_semtimedop */
+ case 220:
+ break;
+ /* linux_fadvise64 */
+ case 221:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "l_loff_t";
+ break;
+ case 2:
+ p = "l_size_t";
+ break;
+ case 3:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_timer_create */
+ case 222:
+ switch(ndx) {
+ case 0:
+ p = "clockid_t";
+ break;
+ case 1:
+ p = "struct sigevent *";
+ break;
+ case 2:
+ p = "l_timer_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_timer_settime */
+ case 223:
+ switch(ndx) {
+ case 0:
+ p = "l_timer_t";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "const struct itimerspec *";
+ break;
+ case 3:
+ p = "struct itimerspec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_timer_gettime */
+ case 224:
+ switch(ndx) {
+ case 0:
+ p = "l_timer_t";
+ break;
+ case 1:
+ p = "struct itimerspec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_timer_getoverrun */
+ case 225:
+ switch(ndx) {
+ case 0:
+ p = "l_timer_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_timer_delete */
+ case 226:
+ switch(ndx) {
+ case 0:
+ p = "l_timer_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_clock_settime */
+ case 227:
+ switch(ndx) {
+ case 0:
+ p = "clockid_t";
+ break;
+ case 1:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_clock_gettime */
+ case 228:
+ switch(ndx) {
+ case 0:
+ p = "clockid_t";
+ break;
+ case 1:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_clock_getres */
+ case 229:
+ switch(ndx) {
+ case 0:
+ p = "clockid_t";
+ break;
+ case 1:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_clock_nanosleep */
+ case 230:
+ switch(ndx) {
+ case 0:
+ p = "clockid_t";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "struct l_timespec *";
+ break;
+ case 3:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_exit_group */
+ case 231:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_epoll_wait */
+ case 232:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct epoll_event *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_epoll_ctl */
+ case 233:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "struct epoll_event *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_tgkill */
+ case 234:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_utimes */
+ case 235:
+ switch(ndx) {
+ case 0:
+ p = "char *";
+ break;
+ case 1:
+ p = "struct l_timeval *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mbind */
+ case 237:
+ break;
+ /* linux_set_mempolicy */
+ case 238:
+ break;
+ /* linux_get_mempolicy */
+ case 239:
+ break;
+ /* linux_mq_open */
+ case 240:
+ break;
+ /* linux_mq_unlink */
+ case 241:
+ break;
+ /* linux_mq_timedsend */
+ case 242:
+ break;
+ /* linux_mq_timedreceive */
+ case 243:
+ break;
+ /* linux_mq_notify */
+ case 244:
+ break;
+ /* linux_mq_getsetattr */
+ case 245:
+ break;
+ /* linux_kexec_load */
+ case 246:
+ break;
+ /* linux_waitid */
+ case 247:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "l_pid_t";
+ break;
+ case 2:
+ p = "l_siginfo_t *";
+ break;
+ case 3:
+ p = "int";
+ break;
+ case 4:
+ p = "struct rusage *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_add_key */
+ case 248:
+ break;
+ /* linux_request_key */
+ case 249:
+ break;
+ /* linux_keyctl */
+ case 250:
+ break;
+ /* linux_ioprio_set */
+ case 251:
+ break;
+ /* linux_ioprio_get */
+ case 252:
+ break;
+ /* linux_inotify_init */
+ case 253:
+ break;
+ /* linux_inotify_add_watch */
+ case 254:
+ break;
+ /* linux_inotify_rm_watch */
+ case 255:
+ break;
+ /* linux_migrate_pages */
+ case 256:
+ break;
+ /* linux_openat */
+ case 257:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mkdirat */
+ case 258:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_mknodat */
+ case 259:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_fchownat */
+ case 260:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_uid_t";
+ break;
+ case 3:
+ p = "l_gid_t";
+ break;
+ case 4:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_futimesat */
+ case 261:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "struct l_timeval *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_newfstatat */
+ case 262:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "char *";
+ break;
+ case 2:
+ p = "struct l_stat64 *";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_unlinkat */
+ case 263:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_renameat */
+ case 264:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "const char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_linkat */
+ case 265:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "const char *";
+ break;
+ case 4:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_symlinkat */
+ case 266:
+ switch(ndx) {
+ case 0:
+ p = "const char *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "const char *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_readlinkat */
+ case 267:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "char *";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_fchmodat */
+ case 268:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_mode_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_faccessat */
+ case 269:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_pselect6 */
+ case 270:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_fd_set *";
+ break;
+ case 2:
+ p = "l_fd_set *";
+ break;
+ case 3:
+ p = "l_fd_set *";
+ break;
+ case 4:
+ p = "struct l_timespec *";
+ break;
+ case 5:
+ p = "l_uintptr_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_ppoll */
+ case 271:
+ switch(ndx) {
+ case 0:
+ p = "struct pollfd *";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "struct l_timespec *";
+ break;
+ case 3:
+ p = "l_sigset_t *";
+ break;
+ case 4:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_unshare */
+ case 272:
+ break;
+ /* linux_set_robust_list */
+ case 273:
+ switch(ndx) {
+ case 0:
+ p = "struct linux_robust_list_head *";
+ break;
+ case 1:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_get_robust_list */
+ case 274:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct linux_robust_list_head *";
+ break;
+ case 2:
+ p = "l_size_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_splice */
+ case 275:
+ break;
+ /* linux_tee */
+ case 276:
+ break;
+ /* linux_sync_file_range */
+ case 277:
+ break;
+ /* linux_vmsplice */
+ case 278:
+ break;
+ /* linux_move_pages */
+ case 279:
+ break;
+ /* linux_utimensat */
+ case 280:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "const struct l_timespec *";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_epoll_pwait */
+ case 281:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct epoll_event *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ case 4:
+ p = "l_sigset_t *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_signalfd */
+ case 282:
+ break;
+ /* linux_timerfd */
+ case 283:
+ break;
+ /* linux_eventfd */
+ case 284:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_fallocate */
+ case 285:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_loff_t";
+ break;
+ case 3:
+ p = "l_loff_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_timerfd_settime */
+ case 286:
+ break;
+ /* linux_timerfd_gettime */
+ case 287:
+ break;
+ /* linux_accept4 */
+ case 288:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_uintptr_t";
+ break;
+ case 2:
+ p = "l_uintptr_t";
+ break;
+ case 3:
+ p = "int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_signalfd4 */
+ case 289:
+ break;
+ /* linux_eventfd2 */
+ case 290:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_epoll_create1 */
+ case 291:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_dup3 */
+ case 292:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_pipe2 */
+ case 293:
+ switch(ndx) {
+ case 0:
+ p = "l_int *";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_inotify_init1 */
+ case 294:
+ break;
+ /* linux_preadv */
+ case 295:
+ break;
+ /* linux_pwritev */
+ case 296:
+ break;
+ /* linux_rt_tsigqueueinfo */
+ case 297:
+ break;
+ /* linux_perf_event_open */
+ case 298:
+ break;
+ /* linux_recvmmsg */
+ case 299:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_mmsghdr *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ case 3:
+ p = "l_uint";
+ break;
+ case 4:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_fanotify_init */
+ case 300:
+ break;
+ /* linux_fanotify_mark */
+ case 301:
+ break;
+ /* linux_prlimit64 */
+ case 302:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_uint";
+ break;
+ case 2:
+ p = "struct rlimit *";
+ break;
+ case 3:
+ p = "struct rlimit *";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_name_to_handle_at */
+ case 303:
+ break;
+ /* linux_open_by_handle_at */
+ case 304:
+ break;
+ /* linux_clock_adjtime */
+ case 305:
+ break;
+ /* linux_syncfs */
+ case 306:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_sendmmsg */
+ case 307:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_mmsghdr *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ case 3:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* linux_setns */
+ case 308:
+ break;
+ /* linux_process_vm_readv */
+ case 309:
+ break;
+ /* linux_process_vm_writev */
+ case 310:
+ break;
+ /* linux_kcmp */
+ case 311:
+ break;
+ /* linux_finit_module */
+ case 312:
+ break;
+ default:
+ break;
+ };
+ if (p != NULL)
+ strlcpy(desc, p, descsz);
+}
+static void
+systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
+{
+ const char *p = NULL;
+ switch (sysnum) {
+#define nosys linux_nosys
+ /* read */
+ case 0:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* write */
+ case 1:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_open */
+ case 2:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* close */
+ case 3:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_newstat */
+ case 4:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_newfstat */
+ case 5:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_newlstat */
+ case 6:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* poll */
+ case 7:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_lseek */
+ case 8:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mmap2 */
+ case 9:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mprotect */
+ case 10:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* munmap */
+ case 11:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_brk */
+ case 12:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rt_sigaction */
+ case 13:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rt_sigprocmask */
+ case 14:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rt_sigreturn */
+ case 15:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_ioctl */
+ case 16:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_pread */
+ case 17:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_pwrite */
+ case 18:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* readv */
+ case 19:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* writev */
+ case 20:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_access */
+ case 21:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_pipe */
+ case 22:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_select */
+ case 23:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* sched_yield */
+ case 24:
+ /* linux_mremap */
+ case 25:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_msync */
+ case 26:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mincore */
+ case 27:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* madvise */
+ case 28:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_shmget */
+ case 29:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_shmat */
+ case 30:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_shmctl */
+ case 31:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* dup */
+ case 32:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* dup2 */
+ case 33:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_pause */
+ case 34:
+ /* linux_nanosleep */
+ case 35:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getitimer */
+ case 36:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_alarm */
+ case 37:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_setitimer */
+ case 38:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getpid */
+ case 39:
+ /* linux_sendfile */
+ case 40:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_socket */
+ case 41:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_connect */
+ case 42:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_accept */
+ case 43:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sendto */
+ case 44:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_recvfrom */
+ case 45:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sendmsg */
+ case 46:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_recvmsg */
+ case 47:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_shutdown */
+ case 48:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_bind */
+ case 49:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_listen */
+ case 50:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getsockname */
+ case 51:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getpeername */
+ case 52:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_socketpair */
+ case 53:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_setsockopt */
+ case 54:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getsockopt */
+ case 55:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_clone */
+ case 56:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_fork */
+ case 57:
+ /* linux_vfork */
+ case 58:
+ /* linux_execve */
+ case 59:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_exit */
+ case 60:
+ if (ndx == 0 || ndx == 1)
+ p = "void";
+ break;
+ /* linux_wait4 */
+ case 61:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_kill */
+ case 62:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_newuname */
+ case 63:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_semget */
+ case 64:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_semop */
+ case 65:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_semctl */
+ case 66:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_shmdt */
+ case 67:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_msgget */
+ case 68:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_msgsnd */
+ case 69:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_msgrcv */
+ case 70:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_msgctl */
+ case 71:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_fcntl */
+ case 72:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* flock */
+ case 73:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* fsync */
+ case 74:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_fdatasync */
+ case 75:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_truncate */
+ case 76:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_ftruncate */
+ case 77:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getdents */
+ case 78:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getcwd */
+ case 79:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_chdir */
+ case 80:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* fchdir */
+ case 81:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rename */
+ case 82:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mkdir */
+ case 83:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rmdir */
+ case 84:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_creat */
+ case 85:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_link */
+ case 86:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_unlink */
+ case 87:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_symlink */
+ case 88:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_readlink */
+ case 89:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_chmod */
+ case 90:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* fchmod */
+ case 91:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_chown */
+ case 92:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* fchown */
+ case 93:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_lchown */
+ case 94:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* umask */
+ case 95:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* gettimeofday */
+ case 96:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getrlimit */
+ case 97:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* getrusage */
+ case 98:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sysinfo */
+ case 99:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_times */
+ case 100:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_ptrace */
+ case 101:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getuid */
+ case 102:
+ /* linux_syslog */
+ case 103:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getgid */
+ case 104:
+ /* setuid */
+ case 105:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* setgid */
+ case 106:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* geteuid */
+ case 107:
+ /* getegid */
+ case 108:
+ /* setpgid */
+ case 109:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getppid */
+ case 110:
+ /* getpgrp */
+ case 111:
+ /* setsid */
+ case 112:
+ /* setreuid */
+ case 113:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* setregid */
+ case 114:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getgroups */
+ case 115:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_setgroups */
+ case 116:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* setresuid */
+ case 117:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* getresuid */
+ case 118:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* setresgid */
+ case 119:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* getresgid */
+ case 120:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* getpgid */
+ case 121:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_setfsuid */
+ case 122:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_setfsgid */
+ case 123:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getsid */
+ case 124:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_capget */
+ case 125:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_capset */
+ case 126:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rt_sigpending */
+ case 127:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rt_sigtimedwait */
+ case 128:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rt_sigqueueinfo */
+ case 129:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_rt_sigsuspend */
+ case 130:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sigaltstack */
+ case 131:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_utime */
+ case 132:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mknod */
+ case 133:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_personality */
+ case 135:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_ustat */
+ case 136:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_statfs */
+ case 137:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_fstatfs */
+ case 138:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sysfs */
+ case 139:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_getpriority */
+ case 140:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* setpriority */
+ case 141:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_setparam */
+ case 142:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_getparam */
+ case 143:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_setscheduler */
+ case 144:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_getscheduler */
+ case 145:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_get_priority_max */
+ case 146:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_get_priority_min */
+ case 147:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_rr_get_interval */
+ case 148:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* mlock */
+ case 149:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* munlock */
+ case 150:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* mlockall */
+ case 151:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* munlockall */
+ case 152:
+ /* linux_vhangup */
+ case 153:
+ /* linux_pivot_root */
+ case 155:
+ /* linux_sysctl */
+ case 156:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_prctl */
+ case 157:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_arch_prctl */
+ case 158:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_adjtimex */
+ case 159:
+ /* linux_setrlimit */
+ case 160:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* chroot */
+ case 161:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* sync */
+ case 162:
+ /* acct */
+ case 163:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* settimeofday */
+ case 164:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mount */
+ case 165:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_umount */
+ case 166:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* swapon */
+ case 167:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_swapoff */
+ case 168:
+ /* linux_reboot */
+ case 169:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sethostname */
+ case 170:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_setdomainname */
+ case 171:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_iopl */
+ case 172:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_create_module */
+ case 174:
+ /* linux_init_module */
+ case 175:
+ /* linux_delete_module */
+ case 176:
+ /* linux_get_kernel_syms */
+ case 177:
+ /* linux_query_module */
+ case 178:
+ /* linux_quotactl */
+ case 179:
+ /* linux_nfsservctl */
+ case 180:
+ /* linux_getpmsg */
+ case 181:
+ /* linux_putpmsg */
+ case 182:
+ /* linux_afs_syscall */
+ case 183:
+ /* linux_tuxcall */
+ case 184:
+ /* linux_security */
+ case 185:
+ /* linux_gettid */
+ case 186:
+ /* linux_setxattr */
+ case 188:
+ /* linux_lsetxattr */
+ case 189:
+ /* linux_fsetxattr */
+ case 190:
+ /* linux_getxattr */
+ case 191:
+ /* linux_lgetxattr */
+ case 192:
+ /* linux_fgetxattr */
+ case 193:
+ /* linux_listxattr */
+ case 194:
+ /* linux_llistxattr */
+ case 195:
+ /* linux_flistxattr */
+ case 196:
+ /* linux_removexattr */
+ case 197:
+ /* linux_lremovexattr */
+ case 198:
+ /* linux_fremovexattr */
+ case 199:
+ /* linux_tkill */
+ case 200:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_time */
+ case 201:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sys_futex */
+ case 202:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_setaffinity */
+ case 203:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sched_getaffinity */
+ case 204:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_set_thread_area */
+ case 205:
+ /* linux_lookup_dcookie */
+ case 212:
+ /* linux_epoll_create */
+ case 213:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_epoll_ctl_old */
+ case 214:
+ /* linux_epoll_wait_old */
+ case 215:
+ /* linux_remap_file_pages */
+ case 216:
+ /* linux_getdents64 */
+ case 217:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_set_tid_address */
+ case 218:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_semtimedop */
+ case 220:
+ /* linux_fadvise64 */
+ case 221:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_timer_create */
+ case 222:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_timer_settime */
+ case 223:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_timer_gettime */
+ case 224:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_timer_getoverrun */
+ case 225:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_timer_delete */
+ case 226:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_clock_settime */
+ case 227:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_clock_gettime */
+ case 228:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_clock_getres */
+ case 229:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_clock_nanosleep */
+ case 230:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_exit_group */
+ case 231:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_epoll_wait */
+ case 232:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_epoll_ctl */
+ case 233:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_tgkill */
+ case 234:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_utimes */
+ case 235:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mbind */
+ case 237:
+ /* linux_set_mempolicy */
+ case 238:
+ /* linux_get_mempolicy */
+ case 239:
+ /* linux_mq_open */
+ case 240:
+ /* linux_mq_unlink */
+ case 241:
+ /* linux_mq_timedsend */
+ case 242:
+ /* linux_mq_timedreceive */
+ case 243:
+ /* linux_mq_notify */
+ case 244:
+ /* linux_mq_getsetattr */
+ case 245:
+ /* linux_kexec_load */
+ case 246:
+ /* linux_waitid */
+ case 247:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_add_key */
+ case 248:
+ /* linux_request_key */
+ case 249:
+ /* linux_keyctl */
+ case 250:
+ /* linux_ioprio_set */
+ case 251:
+ /* linux_ioprio_get */
+ case 252:
+ /* linux_inotify_init */
+ case 253:
+ /* linux_inotify_add_watch */
+ case 254:
+ /* linux_inotify_rm_watch */
+ case 255:
+ /* linux_migrate_pages */
+ case 256:
+ /* linux_openat */
+ case 257:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mkdirat */
+ case 258:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_mknodat */
+ case 259:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_fchownat */
+ case 260:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_futimesat */
+ case 261:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_newfstatat */
+ case 262:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_unlinkat */
+ case 263:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_renameat */
+ case 264:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_linkat */
+ case 265:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_symlinkat */
+ case 266:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_readlinkat */
+ case 267:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_fchmodat */
+ case 268:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_faccessat */
+ case 269:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_pselect6 */
+ case 270:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_ppoll */
+ case 271:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_unshare */
+ case 272:
+ /* linux_set_robust_list */
+ case 273:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_get_robust_list */
+ case 274:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_splice */
+ case 275:
+ /* linux_tee */
+ case 276:
+ /* linux_sync_file_range */
+ case 277:
+ /* linux_vmsplice */
+ case 278:
+ /* linux_move_pages */
+ case 279:
+ /* linux_utimensat */
+ case 280:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_epoll_pwait */
+ case 281:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_signalfd */
+ case 282:
+ /* linux_timerfd */
+ case 283:
+ /* linux_eventfd */
+ case 284:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_fallocate */
+ case 285:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_timerfd_settime */
+ case 286:
+ /* linux_timerfd_gettime */
+ case 287:
+ /* linux_accept4 */
+ case 288:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_signalfd4 */
+ case 289:
+ /* linux_eventfd2 */
+ case 290:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_epoll_create1 */
+ case 291:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_dup3 */
+ case 292:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_pipe2 */
+ case 293:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_inotify_init1 */
+ case 294:
+ /* linux_preadv */
+ case 295:
+ /* linux_pwritev */
+ case 296:
+ /* linux_rt_tsigqueueinfo */
+ case 297:
+ /* linux_perf_event_open */
+ case 298:
+ /* linux_recvmmsg */
+ case 299:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_fanotify_init */
+ case 300:
+ /* linux_fanotify_mark */
+ case 301:
+ /* linux_prlimit64 */
+ case 302:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_name_to_handle_at */
+ case 303:
+ /* linux_open_by_handle_at */
+ case 304:
+ /* linux_clock_adjtime */
+ case 305:
+ /* linux_syncfs */
+ case 306:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_sendmmsg */
+ case 307:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* linux_setns */
+ case 308:
+ /* linux_process_vm_readv */
+ case 309:
+ /* linux_process_vm_writev */
+ case 310:
+ /* linux_kcmp */
+ case 311:
+ /* linux_finit_module */
+ case 312:
+ default:
+ break;
+ };
+ if (p != NULL)
+ strlcpy(desc, p, descsz);
+}
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
new file mode 100644
index 000000000000..e9ab8b369480
--- /dev/null
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -0,0 +1,946 @@
+/*-
+ * Copyright (c) 2013 Dmitry Chagin
+ * Copyright (c) 2004 Tim J. Robbins
+ * Copyright (c) 2003 Peter Wemm
+ * Copyright (c) 2002 Doug Rabson
+ * Copyright (c) 1998-1999 Andrew Gallatin
+ * Copyright (c) 1994-1996 Søren Schmidt
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+
+#define __ELF_WORD_SIZE 64
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/exec.h>
+#include <sys/fcntl.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
+#include <sys/signalvar.h>
+#include <sys/sysctl.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/vnode.h>
+#include <sys/eventhandler.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_param.h>
+
+#include <machine/cpu.h>
+#include <machine/md_var.h>
+#include <machine/pcb.h>
+#include <machine/specialreg.h>
+
+#include <amd64/linux/linux.h>
+#include <amd64/linux/linux_proto.h>
+#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_futex.h>
+#include <compat/linux/linux_ioctl.h>
+#include <compat/linux/linux_mib.h>
+#include <compat/linux/linux_misc.h>
+#include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_sysproto.h>
+#include <compat/linux/linux_util.h>
+#include <compat/linux/linux_vdso.h>
+
+MODULE_VERSION(linux64, 1);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define SHELLMAGIC 0x2123 /* #! */
+#else
+#define SHELLMAGIC 0x2321
+#endif
+
+#if defined(DEBUG)
+SYSCTL_PROC(_compat_linux, OID_AUTO, debug,
+ CTLTYPE_STRING | CTLFLAG_RW,
+ 0, 0, linux_sysctl_debug, "A",
+ "Linux 64 debugging control");
+#endif
+
+/*
+ * Allow the this functions to use the ldebug() facility
+ * even though they are not syscalls themselves. Map them
+ * to syscall 0. This is slightly less bogus than using
+ * ldebug(sigreturn).
+ */
+#define LINUX_SYS_linux_rt_sendsig 0
+
+const char *linux_kplatform;
+static int linux_szsigcode;
+static vm_object_t linux_shared_page_obj;
+static char *linux_shared_page_mapping;
+extern char _binary_linux_locore_o_start;
+extern char _binary_linux_locore_o_end;
+
+extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
+
+SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
+
+static register_t * linux_copyout_strings(struct image_params *imgp);
+static int elf_linux_fixup(register_t **stack_base,
+ struct image_params *iparams);
+static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel);
+static void linux_vdso_install(void *param);
+static void linux_vdso_deinstall(void *param);
+static void linux_set_syscall_retval(struct thread *td, int error);
+static int linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
+static void linux_exec_setregs(struct thread *td, struct image_params *imgp,
+ u_long stack);
+
+/*
+ * Linux syscalls return negative errno's, we do positive and map them
+ * Reference:
+ * FreeBSD: src/sys/sys/errno.h
+ * Linux: linux-2.6.17.8/include/asm-generic/errno-base.h
+ * linux-2.6.17.8/include/asm-generic/errno.h
+ */
+static int bsd_to_linux_errno[ELAST + 1] = {
+ -0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
+ -10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
+ -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
+ -30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
+ -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
+ -100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
+ -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
+ -116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
+ -6, -6, -43, -42, -75,-125, -84, -95, -16, -74,
+ -72, -67, -71
+};
+
+#define LINUX_T_UNKNOWN 255
+static int _bsd_to_linux_trapcode[] = {
+ LINUX_T_UNKNOWN, /* 0 */
+ 6, /* 1 T_PRIVINFLT */
+ LINUX_T_UNKNOWN, /* 2 */
+ 3, /* 3 T_BPTFLT */
+ LINUX_T_UNKNOWN, /* 4 */
+ LINUX_T_UNKNOWN, /* 5 */
+ 16, /* 6 T_ARITHTRAP */
+ 254, /* 7 T_ASTFLT */
+ LINUX_T_UNKNOWN, /* 8 */
+ 13, /* 9 T_PROTFLT */
+ 1, /* 10 T_TRCTRAP */
+ LINUX_T_UNKNOWN, /* 11 */
+ 14, /* 12 T_PAGEFLT */
+ LINUX_T_UNKNOWN, /* 13 */
+ 17, /* 14 T_ALIGNFLT */
+ LINUX_T_UNKNOWN, /* 15 */
+ LINUX_T_UNKNOWN, /* 16 */
+ LINUX_T_UNKNOWN, /* 17 */
+ 0, /* 18 T_DIVIDE */
+ 2, /* 19 T_NMI */
+ 4, /* 20 T_OFLOW */
+ 5, /* 21 T_BOUND */
+ 7, /* 22 T_DNA */
+ 8, /* 23 T_DOUBLEFLT */
+ 9, /* 24 T_FPOPFLT */
+ 10, /* 25 T_TSSFLT */
+ 11, /* 26 T_SEGNPFLT */
+ 12, /* 27 T_STKFLT */
+ 18, /* 28 T_MCHK */
+ 19, /* 29 T_XMMFLT */
+ 15 /* 30 T_RESERVED */
+};
+#define bsd_to_linux_trapcode(code) \
+ ((code)<sizeof(_bsd_to_linux_trapcode)/sizeof(*_bsd_to_linux_trapcode)? \
+ _bsd_to_linux_trapcode[(code)]: \
+ LINUX_T_UNKNOWN)
+
+LINUX_VDSO_SYM_INTPTR(linux_rt_sigcode);
+LINUX_VDSO_SYM_CHAR(linux_platform);
+
+/*
+ * If FreeBSD & Linux have a difference of opinion about what a trap
+ * means, deal with it here.
+ *
+ * MPSAFE
+ */
+static int
+translate_traps(int signal, int trap_code)
+{
+
+ if (signal != SIGBUS)
+ return signal;
+ switch (trap_code) {
+ case T_PROTFLT:
+ case T_TSSFLT:
+ case T_DOUBLEFLT:
+ case T_PAGEFLT:
+ return SIGSEGV;
+ default:
+ return signal;
+ }
+}
+
+static int
+linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+{
+ struct proc *p;
+ struct trapframe *frame;
+
+ p = td->td_proc;
+ frame = td->td_frame;
+
+ sa->args[0] = frame->tf_rdi;
+ sa->args[1] = frame->tf_rsi;
+ sa->args[2] = frame->tf_rdx;
+ sa->args[3] = frame->tf_rcx;
+ sa->args[4] = frame->tf_r8;
+ sa->args[5] = frame->tf_r9;
+ sa->code = frame->tf_rax;
+
+ if (sa->code >= p->p_sysent->sv_size)
+ /* nosys */
+ sa->callp = &p->p_sysent->sv_table[LINUX_SYS_MAXSYSCALL];
+ else
+ sa->callp = &p->p_sysent->sv_table[sa->code];
+ sa->narg = sa->callp->sy_narg;
+
+ td->td_retval[0] = 0;
+ return (0);
+}
+
+static void
+linux_set_syscall_retval(struct thread *td, int error)
+{
+ struct trapframe *frame = td->td_frame;
+
+ /*
+ * On Linux only %rcx and %r11 values are not preserved across
+ * the syscall.
+ * So, do not clobber %rdx and %r10
+ */
+ td->td_retval[1] = frame->tf_rdx;
+ frame->tf_r10 = frame->tf_rcx;
+
+ cpu_set_syscall_retval(td, error);
+
+ /* Restore all registers. */
+ set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
+}
+
+static int
+elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
+{
+ Elf_Auxargs *args;
+ Elf_Addr *base;
+ Elf_Addr *pos;
+ struct ps_strings *arginfo;
+ struct proc *p;
+
+ p = imgp->proc;
+ arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
+
+ KASSERT(curthread->td_proc == imgp->proc,
+ ("unsafe elf_linux_fixup(), should be curproc"));
+ base = (Elf64_Addr *)*stack_base;
+ args = (Elf64_Auxargs *)imgp->auxargs;
+ pos = base + (imgp->args->argc + imgp->args->envc + 2);
+
+ AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO_EHDR,
+ imgp->proc->p_sysent->sv_shared_page_base);
+ AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);
+ AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz);
+ AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
+ AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
+ AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);
+ AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz);
+ AUXARGS_ENTRY(pos, AT_BASE, args->base);
+ AUXARGS_ENTRY(pos, AT_FLAGS, args->flags);
+ AUXARGS_ENTRY(pos, AT_ENTRY, args->entry);
+ AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
+ AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
+ AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
+ AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
+ AUXARGS_ENTRY(pos, LINUX_AT_SECURE, 0);
+ AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(linux_platform));
+ AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, imgp->canary);
+ if (imgp->execpathp != 0)
+ AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, imgp->execpathp);
+ if (args->execfd != -1)
+ AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
+ AUXARGS_ENTRY(pos, AT_NULL, 0);
+ free(imgp->auxargs, M_TEMP);
+ imgp->auxargs = NULL;
+
+ base--;
+ suword(base, (uint64_t)imgp->args->argc);
+
+ *stack_base = (register_t *)base;
+ return (0);
+}
+
+/*
+ * Copy strings out to the new process address space, constructing new arg
+ * and env vector tables. Return a pointer to the base so that it can be used
+ * as the initial stack pointer.
+ */
+static register_t *
+linux_copyout_strings(struct image_params *imgp)
+{
+ int argc, envc;
+ char **vectp;
+ char *stringp, *destp;
+ register_t *stack_base;
+ struct ps_strings *arginfo;
+ char canary[LINUX_AT_RANDOM_LEN];
+ size_t execpath_len;
+ struct proc *p;
+
+ /*
+ * Calculate string base and vector table pointers.
+ */
+ if (imgp->execpath != NULL && imgp->auxargs != NULL)
+ execpath_len = strlen(imgp->execpath) + 1;
+ else
+ execpath_len = 0;
+
+ p = imgp->proc;
+ arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
+ destp = (caddr_t)arginfo - SPARE_USRSPACE -
+ roundup(sizeof(canary), sizeof(char *)) -
+ roundup(execpath_len, sizeof(char *)) -
+ roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
+
+ if (execpath_len != 0) {
+ imgp->execpathp = (uintptr_t)arginfo - execpath_len;
+ copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len);
+ }
+
+ /*
+ * Prepare the canary for SSP.
+ */
+ arc4rand(canary, sizeof(canary), 0);
+ imgp->canary = (uintptr_t)arginfo -
+ roundup(execpath_len, sizeof(char *)) -
+ roundup(sizeof(canary), sizeof(char *));
+ copyout(canary, (void *)imgp->canary, sizeof(canary));
+
+ /*
+ * If we have a valid auxargs ptr, prepare some room
+ * on the stack.
+ */
+ if (imgp->auxargs) {
+ /*
+ * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
+ * lower compatibility.
+ */
+ imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size :
+ (LINUX_AT_COUNT * 2);
+
+ /*
+ * The '+ 2' is for the null pointers at the end of each of
+ * the arg and env vector sets,and imgp->auxarg_size is room
+ * for argument of Runtime loader.
+ */
+ vectp = (char **)(destp - (imgp->args->argc +
+ imgp->args->envc + 2 + imgp->auxarg_size) * sizeof(char *));
+
+ } else {
+ /*
+ * The '+ 2' is for the null pointers at the end of each of
+ * the arg and env vector sets
+ */
+ vectp = (char **)(destp - (imgp->args->argc +
+ imgp->args->envc + 2) * sizeof(char *));
+ }
+
+ /*
+ * vectp also becomes our initial stack base
+ */
+ stack_base = (register_t *)vectp;
+
+ stringp = imgp->args->begin_argv;
+ argc = imgp->args->argc;
+ envc = imgp->args->envc;
+
+ /*
+ * Copy out strings - arguments and environment.
+ */
+ copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
+
+ /*
+ * Fill in "ps_strings" struct for ps, w, etc.
+ */
+ suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp);
+ suword(&arginfo->ps_nargvstr, argc);
+
+ /*
+ * Fill in argument portion of vector table.
+ */
+ for (; argc > 0; --argc) {
+ suword(vectp++, (long)(intptr_t)destp);
+ while (*stringp++ != 0)
+ destp++;
+ destp++;
+ }
+
+ /* a null vector table pointer separates the argp's from the envp's */
+ suword(vectp++, 0);
+
+ suword(&arginfo->ps_envstr, (long)(intptr_t)vectp);
+ suword(&arginfo->ps_nenvstr, envc);
+
+ /*
+ * Fill in environment portion of vector table.
+ */
+ for (; envc > 0; --envc) {
+ suword(vectp++, (long)(intptr_t)destp);
+ while (*stringp++ != 0)
+ destp++;
+ destp++;
+ }
+
+ /* end of vector table is a null pointer */
+ suword(vectp, 0);
+ return (stack_base);
+}
+
+/*
+ * Reset registers to default values on exec.
+ */
+static void
+linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
+{
+ struct trapframe *regs = td->td_frame;
+ struct pcb *pcb = td->td_pcb;
+
+ mtx_lock(&dt_lock);
+ if (td->td_proc->p_md.md_ldt != NULL)
+ user_ldt_free(td);
+ else
+ mtx_unlock(&dt_lock);
+
+ pcb->pcb_fsbase = 0;
+ pcb->pcb_gsbase = 0;
+ clear_pcb_flags(pcb, PCB_32BIT);
+ pcb->pcb_initial_fpucw = __LINUX_NPXCW__;
+ set_pcb_flags(pcb, PCB_FULL_IRET);
+
+ bzero((char *)regs, sizeof(struct trapframe));
+ regs->tf_rip = imgp->entry_addr;
+ regs->tf_rsp = stack;
+ regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T);
+ regs->tf_ss = _udatasel;
+ regs->tf_cs = _ucodesel;
+ regs->tf_ds = _udatasel;
+ regs->tf_es = _udatasel;
+ regs->tf_fs = _ufssel;
+ regs->tf_gs = _ugssel;
+ regs->tf_flags = TF_HASSEGS;
+
+ /*
+ * Reset the hardware debug registers if they were in use.
+ * They won't have any meaning for the newly exec'd process.
+ */
+ if (pcb->pcb_flags & PCB_DBREGS) {
+ pcb->pcb_dr0 = 0;
+ pcb->pcb_dr1 = 0;
+ pcb->pcb_dr2 = 0;
+ pcb->pcb_dr3 = 0;
+ pcb->pcb_dr6 = 0;
+ pcb->pcb_dr7 = 0;
+ if (pcb == curpcb) {
+ /*
+ * Clear the debug registers on the running
+ * CPU, otherwise they will end up affecting
+ * the next process we switch to.
+ */
+ reset_dbregs();
+ }
+ clear_pcb_flags(pcb, PCB_DBREGS);
+ }
+
+ /*
+ * Drop the FP state if we hold it, so that the process gets a
+ * clean FP state if it uses the FPU again.
+ */
+ fpstate_drop(td);
+}
+
+/*
+ * Copied from amd64/amd64/machdep.c
+ *
+ * XXX fpu state need? don't think so
+ */
+int
+linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
+{
+ struct proc *p;
+ struct l_ucontext uc;
+ struct l_sigcontext *context;
+ struct trapframe *regs;
+ unsigned long rflags;
+ int error;
+ ksiginfo_t ksi;
+
+ regs = td->td_frame;
+ error = copyin((void *)regs->tf_rbx, &uc, sizeof(uc));
+ if (error != 0)
+ return (error);
+
+ p = td->td_proc;
+ context = &uc.uc_mcontext;
+ rflags = context->sc_rflags;
+
+ /*
+ * Don't allow users to change privileged or reserved flags.
+ */
+ /*
+ * XXX do allow users to change the privileged flag PSL_RF.
+ * The cpu sets PSL_RF in tf_rflags for faults. Debuggers
+ * should sometimes set it there too. tf_rflags is kept in
+ * the signal context during signal handling and there is no
+ * other place to remember it, so the PSL_RF bit may be
+ * corrupted by the signal handler without us knowing.
+ * Corruption of the PSL_RF bit at worst causes one more or
+ * one less debugger trap, so allowing it is fairly harmless.
+ */
+
+#define RFLAG_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
+ if (!RFLAG_SECURE(rflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
+ printf("linux_rt_sigreturn: rflags = 0x%lx\n", rflags);
+ return (EINVAL);
+ }
+
+ /*
+ * Don't allow users to load a valid privileged %cs. Let the
+ * hardware check for invalid selectors, excess privilege in
+ * other selectors, invalid %eip's and invalid %esp's.
+ */
+#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
+ if (!CS_SECURE(context->sc_cs)) {
+ printf("linux_rt_sigreturn: cs = 0x%x\n", context->sc_cs);
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGBUS;
+ ksi.ksi_code = BUS_OBJERR;
+ ksi.ksi_trapno = T_PROTFLT;
+ ksi.ksi_addr = (void *)regs->tf_rip;
+ trapsignal(td, &ksi);
+ return (EINVAL);
+ }
+
+ PROC_LOCK(p);
+ linux_to_bsd_sigset(&uc.uc_sigmask, &td->td_sigmask);
+ SIG_CANTMASK(td->td_sigmask);
+ signotify(td);
+ PROC_UNLOCK(p);
+
+ regs->tf_rdi = context->sc_rdi;
+ regs->tf_rsi = context->sc_rsi;
+ regs->tf_rdx = context->sc_rdx;
+ regs->tf_rbp = context->sc_rbp;
+ regs->tf_rbx = context->sc_rbx;
+ regs->tf_rcx = context->sc_rcx;
+ regs->tf_rax = context->sc_rax;
+ regs->tf_rip = context->sc_rip;
+ regs->tf_rsp = context->sc_rsp;
+ regs->tf_r8 = context->sc_r8;
+ regs->tf_r9 = context->sc_r9;
+ regs->tf_r10 = context->sc_r10;
+ regs->tf_r11 = context->sc_r11;
+ regs->tf_r12 = context->sc_r12;
+ regs->tf_r13 = context->sc_r13;
+ regs->tf_r14 = context->sc_r14;
+ regs->tf_r15 = context->sc_r15;
+ regs->tf_cs = context->sc_cs;
+ regs->tf_err = context->sc_err;
+ regs->tf_rflags = rflags;
+
+ set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
+ return (EJUSTRETURN);
+}
+
+/*
+ * copied from amd64/amd64/machdep.c
+ *
+ * Send an interrupt to process.
+ */
+static void
+linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
+{
+ struct l_rt_sigframe sf, *sfp;
+ struct proc *p;
+ struct thread *td;
+ struct sigacts *psp;
+ caddr_t sp;
+ struct trapframe *regs;
+ int sig, code;
+ int oonstack;
+
+ td = curthread;
+ p = td->td_proc;
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ sig = ksi->ksi_signo;
+ psp = p->p_sigacts;
+ code = ksi->ksi_code;
+ mtx_assert(&psp->ps_mtx, MA_OWNED);
+ regs = td->td_frame;
+ oonstack = sigonstack(regs->tf_rsp);
+
+ LINUX_CTR4(rt_sendsig, "%p, %d, %p, %u",
+ catcher, sig, mask, code);
+
+ /* Allocate space for the signal handler context. */
+ if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
+ SIGISMEMBER(psp->ps_sigonstack, sig)) {
+ sp = td->td_sigstk.ss_sp + td->td_sigstk.ss_size -
+ sizeof(struct l_rt_sigframe);
+ } else
+ sp = (caddr_t)regs->tf_rsp - sizeof(struct l_rt_sigframe) - 128;
+ /* Align to 16 bytes. */
+ sfp = (struct l_rt_sigframe *)((unsigned long)sp & ~0xFul);
+ mtx_unlock(&psp->ps_mtx);
+
+ /* Translate the signal. */
+ sig = bsd_to_linux_signal(sig);
+
+ /* Save user context. */
+ bzero(&sf, sizeof(sf));
+ bsd_to_linux_sigset(mask, &sf.sf_sc.uc_sigmask);
+ bsd_to_linux_sigset(mask, &sf.sf_sc.uc_mcontext.sc_mask);
+
+ sf.sf_sc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp);
+ sf.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size;
+ sf.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
+ ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
+ PROC_UNLOCK(p);
+
+ sf.sf_sc.uc_mcontext.sc_rdi = regs->tf_rdi;
+ sf.sf_sc.uc_mcontext.sc_rsi = regs->tf_rsi;
+ sf.sf_sc.uc_mcontext.sc_rdx = regs->tf_rdx;
+ sf.sf_sc.uc_mcontext.sc_rbp = regs->tf_rbp;
+ sf.sf_sc.uc_mcontext.sc_rbx = regs->tf_rbx;
+ sf.sf_sc.uc_mcontext.sc_rcx = regs->tf_rcx;
+ sf.sf_sc.uc_mcontext.sc_rax = regs->tf_rax;
+ sf.sf_sc.uc_mcontext.sc_rip = regs->tf_rip;
+ sf.sf_sc.uc_mcontext.sc_rsp = regs->tf_rsp;
+ sf.sf_sc.uc_mcontext.sc_r8 = regs->tf_r8;
+ sf.sf_sc.uc_mcontext.sc_r9 = regs->tf_r9;
+ sf.sf_sc.uc_mcontext.sc_r10 = regs->tf_r10;
+ sf.sf_sc.uc_mcontext.sc_r11 = regs->tf_r11;
+ sf.sf_sc.uc_mcontext.sc_r12 = regs->tf_r12;
+ sf.sf_sc.uc_mcontext.sc_r13 = regs->tf_r13;
+ sf.sf_sc.uc_mcontext.sc_r14 = regs->tf_r14;
+ sf.sf_sc.uc_mcontext.sc_r15 = regs->tf_r15;
+ sf.sf_sc.uc_mcontext.sc_cs = regs->tf_cs;
+ sf.sf_sc.uc_mcontext.sc_rflags = regs->tf_rflags;
+ sf.sf_sc.uc_mcontext.sc_err = regs->tf_err;
+ sf.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
+ sf.sf_sc.uc_mcontext.sc_cr2 = (register_t)ksi->ksi_addr;
+
+ /* Build the argument list for the signal handler. */
+ regs->tf_rdi = sig; /* arg 1 in %rdi */
+ regs->tf_rax = 0;
+ regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */
+ regs->tf_rdx = (register_t)&sfp->sf_sc; /* arg 3 in %rdx */
+
+ sf.sf_handler = catcher;
+ /* Fill in POSIX parts */
+ ksiginfo_to_lsiginfo(ksi, &sf.sf_si, sig);
+
+ /*
+ * Copy the sigframe out to the user's stack.
+ */
+ if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
+#ifdef DEBUG
+ printf("process %ld has trashed its stack\n", (long)p->p_pid);
+#endif
+ PROC_LOCK(p);
+ sigexit(td, SIGILL);
+ }
+
+ regs->tf_rsp = (long)sfp;
+ regs->tf_rip = linux_rt_sigcode;
+ regs->tf_rflags &= ~(PSL_T | PSL_D);
+ regs->tf_cs = _ucodesel;
+ set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
+ PROC_LOCK(p);
+ mtx_lock(&psp->ps_mtx);
+}
+
+/*
+ * If a linux binary is exec'ing something, try this image activator
+ * first. We override standard shell script execution in order to
+ * be able to modify the interpreter path. We only do this if a linux
+ * binary is doing the exec, so we do not create an EXEC module for it.
+ */
+static int exec_linux_imgact_try(struct image_params *iparams);
+
+static int
+exec_linux_imgact_try(struct image_params *imgp)
+{
+ const char *head = (const char *)imgp->image_header;
+ char *rpath;
+ int error = -1, len;
+
+ /*
+ * The interpreter for shell scripts run from a linux binary needs
+ * to be located in /compat/linux if possible in order to recursively
+ * maintain linux path emulation.
+ */
+ if (((const short *)head)[0] == SHELLMAGIC) {
+ /*
+ * Run our normal shell image activator. If it succeeds
+ * attempt to use the alternate path for the interpreter.
+ * If an alternate path is found, use our stringspace
+ * to store it.
+ */
+ if ((error = exec_shell_imgact(imgp)) == 0) {
+ linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
+ imgp->interpreter_name, UIO_SYSSPACE,
+ &rpath, 0, AT_FDCWD);
+ if (rpath != NULL) {
+ len = strlen(rpath) + 1;
+
+ if (len <= MAXSHELLCMDLEN)
+ memcpy(imgp->interpreter_name,
+ rpath, len);
+ free(rpath, M_TEMP);
+ }
+ }
+ }
+ return(error);
+}
+
+struct sysentvec elf_linux_sysvec = {
+ .sv_size = LINUX_SYS_MAXSYSCALL,
+ .sv_table = linux_sysent,
+ .sv_mask = 0,
+ .sv_sigsize = 0,
+ .sv_sigtbl = NULL,
+ .sv_errsize = ELAST + 1,
+ .sv_errtbl = bsd_to_linux_errno,
+ .sv_transtrap = translate_traps,
+ .sv_fixup = elf_linux_fixup,
+ .sv_sendsig = linux_rt_sendsig,
+ .sv_sigcode = &_binary_linux_locore_o_start,
+ .sv_szsigcode = &linux_szsigcode,
+ .sv_prepsyscall = NULL,
+ .sv_name = "Linux ELF64",
+ .sv_coredump = elf64_coredump,
+ .sv_imgact_try = exec_linux_imgact_try,
+ .sv_minsigstksz = LINUX_MINSIGSTKSZ,
+ .sv_pagesize = PAGE_SIZE,
+ .sv_minuser = VM_MIN_ADDRESS,
+ .sv_maxuser = VM_MAXUSER_ADDRESS,
+ .sv_usrstack = USRSTACK,
+ .sv_psstrings = PS_STRINGS,
+ .sv_stackprot = VM_PROT_ALL,
+ .sv_copyout_strings = linux_copyout_strings,
+ .sv_setregs = linux_exec_setregs,
+ .sv_fixlimit = NULL,
+ .sv_maxssiz = NULL,
+ .sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP,
+ .sv_set_syscall_retval = linux_set_syscall_retval,
+ .sv_fetch_syscall_args = linux_fetch_syscall_args,
+ .sv_syscallnames = NULL,
+ .sv_shared_page_base = SHAREDPAGE,
+ .sv_shared_page_len = PAGE_SIZE,
+ .sv_schedtail = linux_schedtail,
+ .sv_thread_detach = linux_thread_detach
+};
+
+static void
+linux_vdso_install(void *param)
+{
+
+ linux_szsigcode = (&_binary_linux_locore_o_end -
+ &_binary_linux_locore_o_start);
+
+ if (linux_szsigcode > elf_linux_sysvec.sv_shared_page_len)
+ panic("Linux invalid vdso size\n");
+
+ __elfN(linux_vdso_fixup)(&elf_linux_sysvec);
+
+ linux_shared_page_obj = __elfN(linux_shared_page_init)
+ (&linux_shared_page_mapping);
+
+ __elfN(linux_vdso_reloc)(&elf_linux_sysvec, SHAREDPAGE);
+
+ bcopy(elf_linux_sysvec.sv_sigcode, linux_shared_page_mapping,
+ linux_szsigcode);
+ elf_linux_sysvec.sv_shared_page_obj = linux_shared_page_obj;
+
+ linux_kplatform = linux_shared_page_mapping +
+ (linux_platform - (caddr_t)SHAREDPAGE);
+}
+SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_ANY,
+ (sysinit_cfunc_t)linux_vdso_install, NULL);
+
+static void
+linux_vdso_deinstall(void *param)
+{
+
+ __elfN(linux_shared_page_fini)(linux_shared_page_obj);
+};
+SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST,
+ (sysinit_cfunc_t)linux_vdso_deinstall, NULL);
+
+static char GNULINUX_ABI_VENDOR[] = "GNU";
+static int GNULINUX_ABI_DESC = 0;
+
+static boolean_t
+linux_trans_osrel(const Elf_Note *note, int32_t *osrel)
+{
+ const Elf32_Word *desc;
+ uintptr_t p;
+
+ p = (uintptr_t)(note + 1);
+ p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
+
+ desc = (const Elf32_Word *)p;
+ if (desc[0] != GNULINUX_ABI_DESC)
+ return (FALSE);
+
+ /*
+ * For linux we encode osrel as follows (see linux_mib.c):
+ * VVVMMMIII (version, major, minor), see linux_mib.c.
+ */
+ *osrel = desc[1] * 1000000 + desc[2] * 1000 + desc[3];
+
+ return (TRUE);
+}
+
+static Elf_Brandnote linux64_brandnote = {
+ .hdr.n_namesz = sizeof(GNULINUX_ABI_VENDOR),
+ .hdr.n_descsz = 16,
+ .hdr.n_type = 1,
+ .vendor = GNULINUX_ABI_VENDOR,
+ .flags = BN_TRANSLATE_OSREL,
+ .trans_osrel = linux_trans_osrel
+};
+
+static Elf64_Brandinfo linux_glibc2brand = {
+ .brand = ELFOSABI_LINUX,
+ .machine = EM_X86_64,
+ .compat_3_brand = "Linux",
+ .emul_path = "/compat/linux",
+ .interp_path = "/lib64/ld-linux-x86-64.so.2",
+ .sysvec = &elf_linux_sysvec,
+ .interp_newpath = NULL,
+ .brand_note = &linux64_brandnote,
+ .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+};
+
+static Elf64_Brandinfo linux_glibc2brandshort = {
+ .brand = ELFOSABI_LINUX,
+ .machine = EM_X86_64,
+ .compat_3_brand = "Linux",
+ .emul_path = "/compat/linux",
+ .interp_path = "/lib64/ld-linux.so.2",
+ .sysvec = &elf_linux_sysvec,
+ .interp_newpath = NULL,
+ .brand_note = &linux64_brandnote,
+ .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE
+};
+
+Elf64_Brandinfo *linux_brandlist[] = {
+ &linux_glibc2brand,
+ &linux_glibc2brandshort,
+ NULL
+};
+
+static int
+linux64_elf_modevent(module_t mod, int type, void *data)
+{
+ Elf64_Brandinfo **brandinfo;
+ int error;
+ struct linux_ioctl_handler **lihp;
+
+ error = 0;
+
+ switch(type) {
+ case MOD_LOAD:
+ for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
+ ++brandinfo)
+ if (elf64_insert_brand_entry(*brandinfo) < 0)
+ error = EINVAL;
+ if (error == 0) {
+ SET_FOREACH(lihp, linux_ioctl_handler_set)
+ linux_ioctl_register_handler(*lihp);
+ LIST_INIT(&futex_list);
+ mtx_init(&futex_mtx, "ftllk64", NULL, MTX_DEF);
+ stclohz = (stathz ? stathz : hz);
+ if (bootverbose)
+ printf("Linux x86-64 ELF exec handler installed\n");
+ } else
+ printf("cannot insert Linux x86-64 ELF brand handler\n");
+ break;
+ case MOD_UNLOAD:
+ for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
+ ++brandinfo)
+ if (elf64_brand_inuse(*brandinfo))
+ error = EBUSY;
+ if (error == 0) {
+ for (brandinfo = &linux_brandlist[0];
+ *brandinfo != NULL; ++brandinfo)
+ if (elf64_remove_brand_entry(*brandinfo) < 0)
+ error = EINVAL;
+ }
+ if (error == 0) {
+ SET_FOREACH(lihp, linux_ioctl_handler_set)
+ linux_ioctl_unregister_handler(*lihp);
+ mtx_destroy(&futex_mtx);
+ if (bootverbose)
+ printf("Linux ELF exec handler removed\n");
+ } else
+ printf("Could not deinstall ELF interpreter entry\n");
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+ return (error);
+}
+
+static moduledata_t linux64_elf_mod = {
+ "linux64elf",
+ linux64_elf_modevent,
+ 0
+};
+
+DECLARE_MODULE_TIED(linux64elf, linux64_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
+MODULE_DEPEND(linux64elf, linux_common, 1, 1, 1);
diff --git a/sys/amd64/linux/linux_vdso.lds.s b/sys/amd64/linux/linux_vdso.lds.s
new file mode 100644
index 000000000000..94f0266095fb
--- /dev/null
+++ b/sys/amd64/linux/linux_vdso.lds.s
@@ -0,0 +1,69 @@
+/*
+ * Linker script for 64-bit vDSO.
+ * Copied from Linux kernel arch/x86/vdso/vdso-layout.lds.S
+ *
+ * $FreeBSD$
+ */
+
+SECTIONS
+{
+ . = . + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+ .data : {
+ *(.data*)
+ *(.sdata*)
+ *(.got.plt) *(.got)
+ *(.gnu.linkonce.d.*)
+ *(.bss*)
+ *(.dynbss*)
+ *(.gnu.linkonce.b.*)
+ }
+
+ .altinstructions : { *(.altinstructions) }
+ .altinstr_replacement : { *(.altinstr_replacement) }
+
+ . = ALIGN(0x100);
+ .text : { *(.test .text*) } :text =0x90909090
+}
+
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
+
+VERSION
+{
+ LINUX_2.6 {
+ global:
+ time;
+ __vdso_time;
+ gettimeofday;
+ __vdso_gettimeofday;
+ getcpu;
+ __vdso_getcpu;
+ clock_gettime;
+ __vdso_clock_gettime;
+ linux_rt_sigcode;
+ linux_platform;
+ local: *;
+ };
+}
diff --git a/sys/amd64/linux/syscalls.conf b/sys/amd64/linux/syscalls.conf
new file mode 100644
index 000000000000..29f37920bba6
--- /dev/null
+++ b/sys/amd64/linux/syscalls.conf
@@ -0,0 +1,11 @@
+# $FreeBSD$
+sysnames="linux_syscalls.c"
+sysproto="linux_proto.h"
+sysproto_h=_LINUX_SYSPROTO_H_
+syshdr="linux_syscall.h"
+syssw="linux_sysent.c"
+sysmk="/dev/null"
+syscallprefix="LINUX_SYS_"
+switchname="linux_sysent"
+namesname="linux_syscallnames"
+systrace="linux_systrace_args.c"
diff --git a/sys/amd64/linux/syscalls.master b/sys/amd64/linux/syscalls.master
new file mode 100644
index 000000000000..d840f8806d4e
--- /dev/null
+++ b/sys/amd64/linux/syscalls.master
@@ -0,0 +1,515 @@
+ $FreeBSD$
+
+; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
+; System call name/number master file (or rather, slave, from LINUX).
+; Processed to create linux_sysent.c, linux_proto.h and linux_syscall.h.
+
+; Columns: number audit type nargs name alt{name,tag,rtyp}/comments
+; number system call number, must be in order
+; audit the audit event associated with the system call
+; A value of AUE_NULL means no auditing, but it also means that
+; there is no audit event for the call at this time. For the
+; case where the event exists, but we don't want auditing, the
+; event should be #defined to AUE_NULL in audit_kevents.h.
+; type one of STD, OBSOL, UNIMPL
+; name psuedo-prototype of syscall routine
+; If one of the following alts is different, then all appear:
+; altname name of system call if different
+; alttag name of args struct tag if different from [o]`name'"_args"
+; altrtyp return type if not int (bogus - syscalls always return int)
+; for UNIMPL/OBSOL, name continues with comments
+
+; types:
+; STD always included
+; OBSOL obsolete, not included in system, only specifies name
+; UNIMPL not implemented, placeholder only
+
+#include <sys/param.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <compat/linux/linux_sysproto.h>
+#include <amd64/linux/linux.h>
+#include <amd64/linux/linux_proto.h>
+
+; Isn't pretty, but there seems to be no other way to trap nosys
+#define nosys linux_nosys
+
+; #ifdef's, etc. may be included, and are copied to the output files.
+
+0 AUE_NULL NOPROTO { int read(int fd, char *buf, \
+ u_int nbyte); }
+1 AUE_NULL NOPROTO { int write(int fd, char *buf, \
+ u_int nbyte); }
+2 AUE_OPEN_RWTC STD { int linux_open(char *path, l_int flags, \
+ l_int mode); }
+3 AUE_CLOSE NOPROTO { int close(int fd); }
+4 AUE_STAT STD { int linux_newstat(char *path, \
+ struct l_newstat *buf); }
+5 AUE_FSTAT STD { int linux_newfstat(l_uint fd, \
+ struct l_newstat *buf); }
+6 AUE_LSTAT STD { int linux_newlstat(char *path, \
+ struct l_newstat *buf); }
+7 AUE_POLL NOPROTO { int poll(struct pollfd*, \
+ unsigned int nfds, int timeout); }
+8 AUE_LSEEK STD { int linux_lseek(l_uint fdes, l_off_t off, \
+ l_int whence); }
+9 AUE_MMAP STD { int linux_mmap2(l_ulong addr, l_ulong len, \
+ l_ulong prot, l_ulong flags, l_ulong fd, \
+ l_ulong pgoff); }
+10 AUE_MPROTECT STD { int linux_mprotect(caddr_t addr, int len, \
+ int prot); }
+11 AUE_MUNMAP NOPROTO { int munmap(caddr_t addr, int len); }
+12 AUE_NULL STD { int linux_brk(l_ulong dsend); }
+13 AUE_NULL STD { int linux_rt_sigaction(l_int sig, \
+ l_sigaction_t *act, l_sigaction_t *oact, \
+ l_size_t sigsetsize); }
+14 AUE_NULL STD { int linux_rt_sigprocmask(l_int how, \
+ l_sigset_t *mask, l_sigset_t *omask, \
+ l_size_t sigsetsize); }
+15 AUE_NULL STD { int linux_rt_sigreturn( \
+ struct l_ucontext *ucp); }
+16 AUE_IOCTL STD { int linux_ioctl(l_uint fd, l_uint cmd, \
+ uintptr_t arg); }
+17 AUE_PREAD STD { int linux_pread(l_uint fd, char *buf, \
+ l_size_t nbyte, l_loff_t offset); }
+18 AUE_PWRITE STD { int linux_pwrite(l_uint fd, char *buf, \
+ l_size_t nbyte, l_loff_t offset); }
+19 AUE_READV NOPROTO { int readv(int fd, struct iovec *iovp, \
+ u_int iovcnt); }
+20 AUE_WRITEV NOPROTO { int writev(int fd, struct iovec *iovp, \
+ u_int iovcnt); }
+21 AUE_ACCESS STD { int linux_access(char *path, l_int amode); }
+22 AUE_PIPE STD { int linux_pipe(l_ulong *pipefds); }
+23 AUE_SELECT STD { int linux_select(l_int nfds, \
+ l_fd_set *readfds, l_fd_set *writefds, \
+ l_fd_set *exceptfds, \
+ struct l_timeval *timeout); }
+24 AUE_NULL NOPROTO { int sched_yield(void); }
+25 AUE_NULL STD { int linux_mremap(l_ulong addr, \
+ l_ulong old_len, l_ulong new_len, \
+ l_ulong flags, l_ulong new_addr); }
+26 AUE_MSYNC STD { int linux_msync(l_ulong addr, \
+ l_size_t len, l_int fl); }
+27 AUE_MINCORE STD { int linux_mincore(l_ulong start, \
+ l_size_t len, u_char *vec); }
+28 AUE_MADVISE NOPROTO { int madvise(void *addr, size_t len, \
+ int behav); }
+29 AUE_NULL STD { int linux_shmget(l_key_t key, l_size_t size, \
+ l_int shmflg); }
+30 AUE_NULL STD { int linux_shmat(l_int shmid, char *shmaddr, \
+ l_int shmflg); }
+31 AUE_NULL STD { int linux_shmctl(l_int shmid, l_int cmd, \
+ struct l_shmid_ds *buf); }
+32 AUE_DUP NOPROTO { int dup(u_int fd); }
+33 AUE_DUP2 NOPROTO { int dup2(u_int from, u_int to); }
+34 AUE_NULL STD { int linux_pause(void); }
+35 AUE_NULL STD { int linux_nanosleep( \
+ const struct l_timespec *rqtp, \
+ struct l_timespec *rmtp); }
+36 AUE_GETITIMER STD { int linux_getitimer(l_int which, \
+ struct l_itimerval *itv); }
+37 AUE_NULL STD { int linux_alarm(l_uint secs); }
+38 AUE_SETITIMER STD { int linux_setitimer(l_int which, \
+ struct l_itimerval *itv, \
+ struct l_itimerval *oitv); }
+39 AUE_GETPID STD { int linux_getpid(void); }
+40 AUE_SENDFILE STD { int linux_sendfile(int out, int in, \
+ l_long *offset, l_size_t count); }
+41 AUE_SOCKET STD { int linux_socket(l_int domain, l_int type, \
+ l_int protocol); }
+42 AUE_CONNECT STD { int linux_connect(l_int s, l_uintptr_t name, \
+ l_int namelen); }
+43 AUE_ACCEPT STD { int linux_accept(l_int s, l_uintptr_t addr, \
+ l_uintptr_t namelen); }
+44 AUE_SENDTO STD { int linux_sendto(l_int s, l_uintptr_t msg, \
+ l_int len, l_int flags, l_uintptr_t to, \
+ l_int tolen); }
+45 AUE_RECVFROM STD { int linux_recvfrom(l_int s, l_uintptr_t buf, \
+ l_size_t len, l_int flags, l_uintptr_t from, \
+ l_uintptr_t fromlen); }
+46 AUE_SENDMSG STD { int linux_sendmsg(l_int s, l_uintptr_t msg, \
+ l_int flags); }
+47 AUE_RECVMSG STD { int linux_recvmsg(l_int s, l_uintptr_t msg, \
+ l_int flags); }
+48 AUE_NULL STD { int linux_shutdown(l_int s, l_int how); }
+49 AUE_BIND STD { int linux_bind(l_int s, l_uintptr_t name, \
+ l_int namelen); }
+50 AUE_LISTEN STD { int linux_listen(l_int s, l_int backlog); }
+51 AUE_GETSOCKNAME STD { int linux_getsockname(l_int s, \
+ l_uintptr_t addr, l_uintptr_t namelen); }
+52 AUE_GETPEERNAME STD { int linux_getpeername(l_int s, \
+ l_uintptr_t addr, l_uintptr_t namelen); }
+53 AUE_SOCKETPAIR STD { int linux_socketpair(l_int domain, \
+ l_int type, l_int protocol, l_uintptr_t rsv); }
+54 AUE_SETSOCKOPT STD { int linux_setsockopt(l_int s, l_int level, \
+ l_int optname, l_uintptr_t optval, \
+ l_int optlen); }
+55 AUE_GETSOCKOPT STD { int linux_getsockopt(l_int s, l_int level, \
+ l_int optname, l_uintptr_t optval, \
+ l_uintptr_t optlen); }
+56 AUE_RFORK STD { int linux_clone(l_int flags, void *stack, \
+ void *parent_tidptr, void * child_tidptr, void *tls ); }
+57 AUE_FORK STD { int linux_fork(void); }
+58 AUE_VFORK STD { int linux_vfork(void); }
+59 AUE_EXECVE STD { int linux_execve(char *path, char **argp, \
+ char **envp); }
+60 AUE_EXIT STD { void linux_exit(int rval); }
+61 AUE_WAIT4 STD { int linux_wait4(l_pid_t pid, \
+ l_int *status, l_int options, \
+ struct rusage *rusage); }
+62 AUE_KILL STD { int linux_kill(l_int pid, l_int signum); }
+63 AUE_NULL STD { int linux_newuname( \
+ struct l_new_utsname *buf); }
+64 AUE_NULL STD { int linux_semget(l_key_t key, \
+ l_int nsems, l_int semflg); }
+65 AUE_NULL STD { int linux_semop(l_int semid, \
+ struct l_sembuf *tsops, l_uint nsops); }
+66 AUE_NULL STD { int linux_semctl(l_int semid, \
+ l_int semnum, l_int cmd, union l_semun arg); }
+67 AUE_NULL STD { int linux_shmdt(char *shmaddr); }
+68 AUE_NULL STD { int linux_msgget(l_key_t key, l_int msgflg); }
+69 AUE_NULL STD { int linux_msgsnd(l_int msqid, \
+ struct l_msgbuf *msgp, l_size_t msgsz, \
+ l_int msgflg); }
+70 AUE_NULL STD { int linux_msgrcv(l_int msqid, \
+ struct l_msgbuf *msgp, l_size_t msgsz, \
+ l_long msgtyp, l_int msgflg); }
+71 AUE_NULL STD { int linux_msgctl(l_int msqid, l_int cmd, \
+ struct l_msqid_ds *buf); }
+72 AUE_FCNTL STD { int linux_fcntl(l_uint fd, l_uint cmd, \
+ l_ulong arg); }
+73 AUE_FLOCK NOPROTO { int flock(int fd, int how); }
+74 AUE_FSYNC NOPROTO { int fsync(int fd); }
+75 AUE_NULL STD { int linux_fdatasync(l_uint fd); }
+76 AUE_TRUNCATE STD { int linux_truncate(char *path, \
+ l_ulong length); }
+77 AUE_FTRUNCATE STD { int linux_ftruncate(l_int fd, l_long length); }
+78 AUE_GETDIRENTRIES STD { int linux_getdents(l_uint fd, void *dent, \
+ l_uint count); }
+79 AUE_GETCWD STD { int linux_getcwd(char *buf, \
+ l_ulong bufsize); }
+80 AUE_CHDIR STD { int linux_chdir(char *path); }
+81 AUE_FCHDIR NOPROTO { int fchdir(int fd); }
+82 AUE_RENAME STD { int linux_rename(char *from, char *to); }
+83 AUE_MKDIR STD { int linux_mkdir(char *path, l_int mode); }
+84 AUE_RMDIR STD { int linux_rmdir(char *path); }
+85 AUE_CREAT STD { int linux_creat(char *path, \
+ l_int mode); }
+86 AUE_LINK STD { int linux_link(char *path, char *to); }
+87 AUE_UNLINK STD { int linux_unlink(char *path); }
+88 AUE_SYMLINK STD { int linux_symlink(char *path, char *to); }
+89 AUE_READLINK STD { int linux_readlink(char *name, char *buf, \
+ l_int count); }
+90 AUE_CHMOD STD { int linux_chmod(char *path, \
+ l_mode_t mode); }
+91 AUE_FCHMOD NOPROTO { int fchmod(int fd, int mode); }
+92 AUE_LCHOWN STD { int linux_chown(char *path, \
+ l_uid_t uid, l_gid_t gid); }
+93 AUE_FCHOWN NOPROTO { int fchown(int fd, int uid, int gid); }
+94 AUE_LCHOWN STD { int linux_lchown(char *path, l_uid_t uid, \
+ l_gid_t gid); }
+95 AUE_UMASK NOPROTO { int umask(int newmask); }
+96 AUE_NULL NOPROTO { int gettimeofday(struct l_timeval *tp, \
+ struct timezone *tzp); }
+97 AUE_GETRLIMIT STD { int linux_getrlimit(l_uint resource, \
+ struct l_rlimit *rlim); }
+98 AUE_GETRUSAGE NOPROTO { int getrusage(int who, struct rusage *rusage); }
+99 AUE_NULL STD { int linux_sysinfo(struct l_sysinfo *info); }
+100 AUE_NULL STD { int linux_times(struct l_times_argv *buf); }
+101 AUE_PTRACE STD { int linux_ptrace(l_long req, l_long pid, \
+ l_long addr, l_long data); }
+102 AUE_GETUID STD { int linux_getuid(void); }
+103 AUE_NULL STD { int linux_syslog(l_int type, char *buf, \
+ l_int len); }
+104 AUE_GETGID STD { int linux_getgid(void); }
+105 AUE_SETUID NOPROTO { int setuid(uid_t uid); }
+106 AUE_SETGID NOPROTO { int setgid(gid_t gid); }
+107 AUE_GETEUID NOPROTO { int geteuid(void); }
+108 AUE_GETEGID NOPROTO { int getegid(void); }
+109 AUE_SETPGRP NOPROTO { int setpgid(int pid, int pgid); }
+110 AUE_GETPPID STD { int linux_getppid(void); }
+111 AUE_GETPGRP NOPROTO { int getpgrp(void); }
+112 AUE_SETSID NOPROTO { int setsid(void); }
+113 AUE_SETREUID NOPROTO { int setreuid(uid_t ruid, uid_t euid); }
+114 AUE_SETREGID NOPROTO { int setregid(gid_t rgid, gid_t egid); }
+115 AUE_GETGROUPS STD { int linux_getgroups(l_int gidsetsize, \
+ l_gid_t *grouplist); }
+116 AUE_SETGROUPS STD { int linux_setgroups(l_int gidsetsize, \
+ l_gid_t *grouplist); }
+117 AUE_SETRESUID NOPROTO { int setresuid(uid_t ruid, uid_t euid, \
+ uid_t suid); }
+118 AUE_GETRESUID NOPROTO { int getresuid(uid_t *ruid, uid_t *euid, \
+ uid_t *suid); }
+119 AUE_SETRESGID NOPROTO { int setresgid(gid_t rgid, gid_t egid, \
+ gid_t sgid); }
+120 AUE_GETRESGID NOPROTO { int getresgid(gid_t *rgid, gid_t *egid, \
+ gid_t *sgid); }
+121 AUE_GETPGID NOPROTO { int getpgid(int pid); }
+122 AUE_SETFSUID STD { int linux_setfsuid(l_uid_t uid); }
+123 AUE_SETFSGID STD { int linux_setfsgid(l_gid_t gid); }
+124 AUE_GETSID STD { int linux_getsid(l_pid_t pid); }
+125 AUE_CAPGET STD { int linux_capget(struct l_user_cap_header *hdrp, \
+ struct l_user_cap_data *datap); }
+126 AUE_CAPSET STD { int linux_capset(struct l_user_cap_header *hdrp, \
+ struct l_user_cap_data *datap); }
+127 AUE_NULL STD { int linux_rt_sigpending(l_sigset_t *set, \
+ l_size_t sigsetsize); }
+128 AUE_NULL STD { int linux_rt_sigtimedwait(l_sigset_t *mask, \
+ l_siginfo_t *ptr, \
+ struct l_timeval *timeout, \
+ l_size_t sigsetsize); }
+129 AUE_NULL STD { int linux_rt_sigqueueinfo(l_pid_t pid, l_int sig, \
+ l_siginfo_t *info); }
+130 AUE_NULL STD { int linux_rt_sigsuspend( \
+ l_sigset_t *newset, \
+ l_size_t sigsetsize); }
+131 AUE_NULL STD { int linux_sigaltstack(l_stack_t *uss, \
+ l_stack_t *uoss); }
+132 AUE_UTIME STD { int linux_utime(char *fname, \
+ struct l_utimbuf *times); }
+133 AUE_MKNOD STD { int linux_mknod(char *path, l_int mode, \
+ l_dev_t dev); }
+134 AUE_USELIB UNIMPL uselib
+135 AUE_PERSONALITY STD { int linux_personality(l_ulong per); }
+136 AUE_NULL STD { int linux_ustat(l_dev_t dev, \
+ struct l_ustat *ubuf); }
+137 AUE_STATFS STD { int linux_statfs(char *path, \
+ struct l_statfs_buf *buf); }
+138 AUE_FSTATFS STD { int linux_fstatfs(l_uint fd, \
+ struct l_statfs_buf *buf); }
+139 AUE_NULL STD { int linux_sysfs(l_int option, \
+ l_ulong arg1, l_ulong arg2); }
+140 AUE_GETPRIORITY STD { int linux_getpriority(int which, int who); }
+141 AUE_SETPRIORITY NOPROTO { int setpriority(int which, int who, \
+ int prio); }
+142 AUE_SCHED_SETPARAM STD { int linux_sched_setparam(l_pid_t pid, \
+ struct l_sched_param *param); }
+143 AUE_SCHED_GETPARAM STD { int linux_sched_getparam(l_pid_t pid, \
+ struct l_sched_param *param); }
+144 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( \
+ l_pid_t pid, l_int policy, \
+ struct l_sched_param *param); }
+145 AUE_SCHED_GETSCHEDULER STD { int linux_sched_getscheduler( \
+ l_pid_t pid); }
+146 AUE_SCHED_GET_PRIORITY_MAX STD { int linux_sched_get_priority_max( \
+ l_int policy); }
+147 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( \
+ l_int policy); }
+148 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval(l_pid_t pid, \
+ struct l_timespec *interval); }
+149 AUE_MLOCK NOPROTO { int mlock(const void *addr, size_t len); }
+150 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, size_t len); }
+151 AUE_MLOCKALL NOPROTO { int mlockall(int how); }
+152 AUE_MUNLOCKALL NOPROTO { int munlockall(void); }
+153 AUE_NULL STD { int linux_vhangup(void); }
+154 AUE_NULL UNIMPL modify_ldt
+155 AUE_PIVOT_ROOT STD { int linux_pivot_root(void); }
+156 AUE_SYSCTL STD { int linux_sysctl( \
+ struct l___sysctl_args *args); }
+157 AUE_PRCTL STD { int linux_prctl(l_int option, l_uintptr_t arg2, \
+ l_uintptr_t arg3, l_uintptr_t arg4, \
+ l_uintptr_t arg5); }
+158 AUE_PRCTL STD { int linux_arch_prctl(l_int code, l_ulong addr); }
+159 AUE_ADJTIME STD { int linux_adjtimex(void); }
+160 AUE_SETRLIMIT STD { int linux_setrlimit(l_uint resource, \
+ struct l_rlimit *rlim); }
+161 AUE_CHROOT NOPROTO { int chroot(char *path); }
+162 AUE_SYNC NOPROTO { int sync(void); }
+163 AUE_ACCT NOPROTO { int acct(char *path); }
+164 AUE_SETTIMEOFDAY NOPROTO { int settimeofday(struct l_timeval *tp, struct timezone *tzp); }
+165 AUE_MOUNT STD { int linux_mount(char *specialfile, \
+ char *dir, char *filesystemtype, \
+ l_ulong rwflag, void *data); }
+166 AUE_UMOUNT STD { int linux_umount(char *path, l_int flags); }
+167 AUE_SWAPON NOPROTO { int swapon(char *name); }
+168 AUE_SWAPOFF STD { int linux_swapoff(void); }
+169 AUE_REBOOT STD { int linux_reboot(l_int magic1, \
+ l_int magic2, l_uint cmd, void *arg); }
+170 AUE_SYSCTL STD { int linux_sethostname(char *hostname, \
+ l_uint len); }
+171 AUE_SYSCTL STD { int linux_setdomainname(char *name, \
+ l_int len); }
+172 AUE_NULL STD { int linux_iopl(l_uint level); }
+173 AUE_NULL UNIMPL ioperm
+174 AUE_NULL STD { int linux_create_module(void); }
+175 AUE_NULL STD { int linux_init_module(void); }
+176 AUE_NULL STD { int linux_delete_module(void); }
+177 AUE_NULL STD { int linux_get_kernel_syms(void); }
+178 AUE_NULL STD { int linux_query_module(void); }
+179 AUE_QUOTACTL STD { int linux_quotactl(void); }
+180 AUE_NULL STD { int linux_nfsservctl(void); }
+181 AUE_GETPMSG STD { int linux_getpmsg(void); }
+182 AUE_PUTPMSG STD { int linux_putpmsg(void); }
+183 AUE_NULL STD { int linux_afs_syscall(void); }
+184 AUE_NULL STD { int linux_tuxcall(void); }
+185 AUE_NULL STD { int linux_security(void); }
+186 AUE_NULL STD { int linux_gettid(void); }
+187 AUE_NULL UNIMPL linux_readahead
+188 AUE_NULL STD { int linux_setxattr(void); }
+189 AUE_NULL STD { int linux_lsetxattr(void); }
+190 AUE_NULL STD { int linux_fsetxattr(void); }
+191 AUE_NULL STD { int linux_getxattr(void); }
+192 AUE_NULL STD { int linux_lgetxattr(void); }
+193 AUE_NULL STD { int linux_fgetxattr(void); }
+194 AUE_NULL STD { int linux_listxattr(void); }
+195 AUE_NULL STD { int linux_llistxattr(void); }
+196 AUE_NULL STD { int linux_flistxattr(void); }
+197 AUE_NULL STD { int linux_removexattr(void); }
+198 AUE_NULL STD { int linux_lremovexattr(void); }
+199 AUE_NULL STD { int linux_fremovexattr(void); }
+200 AUE_NULL STD { int linux_tkill(int tid, int sig); }
+201 AUE_NULL STD { int linux_time(l_time_t *tm); }
+202 AUE_NULL STD { int linux_sys_futex(void *uaddr, int op, int val, \
+ struct l_timespec *timeout, void *uaddr2, int val3); }
+203 AUE_NULL STD { int linux_sched_setaffinity(l_pid_t pid, l_uint len, \
+ l_ulong *user_mask_ptr); }
+204 AUE_NULL STD { int linux_sched_getaffinity(l_pid_t pid, l_uint len, \
+ l_ulong *user_mask_ptr); }
+205 AUE_NULL STD { int linux_set_thread_area(void); }
+206 AUE_NULL UNIMPL linux_io_setup
+207 AUE_NULL UNIMPL linux_io_destroy
+208 AUE_NULL UNIMPL linux_io_getevents
+209 AUE_NULL UNIMPL inux_io_submit
+210 AUE_NULL UNIMPL linux_io_cancel
+211 AUE_NULL UNIMPL linux_get_thread_area
+212 AUE_NULL STD { int linux_lookup_dcookie(void); }
+213 AUE_NULL STD { int linux_epoll_create(l_int size); }
+214 AUE_NULL STD { int linux_epoll_ctl_old(void); }
+215 AUE_NULL STD { int linux_epoll_wait_old(void); }
+216 AUE_NULL STD { int linux_remap_file_pages(void); }
+217 AUE_GETDIRENTRIES STD { int linux_getdents64(l_uint fd, \
+ void *dirent, l_uint count); }
+218 AUE_NULL STD { int linux_set_tid_address(int *tidptr); }
+219 AUE_NULL UNIMPL restart_syscall
+220 AUE_NULL STD { int linux_semtimedop(void); }
+221 AUE_NULL STD { int linux_fadvise64(int fd, l_loff_t offset, \
+ l_size_t len, int advice); }
+222 AUE_NULL STD { int linux_timer_create(clockid_t clock_id, \
+ struct sigevent *evp, l_timer_t *timerid); }
+223 AUE_NULL STD { int linux_timer_settime(l_timer_t timerid, l_int flags, \
+ const struct itimerspec *new, struct itimerspec *old); }
+224 AUE_NULL STD { int linux_timer_gettime(l_timer_t timerid, struct itimerspec *setting); }
+225 AUE_NULL STD { int linux_timer_getoverrun(l_timer_t timerid); }
+226 AUE_NULL STD { int linux_timer_delete(l_timer_t timerid); }
+227 AUE_CLOCK_SETTIME STD { int linux_clock_settime(clockid_t which, struct l_timespec *tp); }
+228 AUE_NULL STD { int linux_clock_gettime(clockid_t which, struct l_timespec *tp); }
+229 AUE_NULL STD { int linux_clock_getres(clockid_t which, struct l_timespec *tp); }
+230 AUE_NULL STD { int linux_clock_nanosleep(clockid_t which, int flags, \
+ struct l_timespec *rqtp, struct l_timespec *rmtp); }
+231 AUE_EXIT STD { int linux_exit_group(int error_code); }
+232 AUE_NULL STD { int linux_epoll_wait(l_int epfd, struct epoll_event *events, \
+ l_int maxevents, l_int timeout); }
+233 AUE_NULL STD { int linux_epoll_ctl(l_int epfd, l_int op, l_int fd, \
+ struct epoll_event *event); }
+234 AUE_NULL STD { int linux_tgkill(int tgid, int pid, int sig); }
+235 AUE_UTIMES STD { int linux_utimes(char *fname, \
+ struct l_timeval *tptr); }
+236 AUE_NULL UNIMPL vserver
+237 AUE_NULL STD { int linux_mbind(void); }
+238 AUE_NULL STD { int linux_set_mempolicy(void); }
+239 AUE_NULL STD { int linux_get_mempolicy(void); }
+240 AUE_NULL STD { int linux_mq_open(void); }
+241 AUE_NULL STD { int linux_mq_unlink(void); }
+242 AUE_NULL STD { int linux_mq_timedsend(void); }
+243 AUE_NULL STD { int linux_mq_timedreceive(void); }
+244 AUE_NULL STD { int linux_mq_notify(void); }
+245 AUE_NULL STD { int linux_mq_getsetattr(void); }
+246 AUE_NULL STD { int linux_kexec_load(void); }
+247 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \
+ l_siginfo_t *info, int options, \
+ struct rusage *rusage); }
+248 AUE_NULL STD { int linux_add_key(void); }
+249 AUE_NULL STD { int linux_request_key(void); }
+250 AUE_NULL STD { int linux_keyctl(void); }
+251 AUE_NULL STD { int linux_ioprio_set(void); }
+252 AUE_NULL STD { int linux_ioprio_get(void); }
+253 AUE_NULL STD { int linux_inotify_init(void); }
+254 AUE_NULL STD { int linux_inotify_add_watch(void); }
+255 AUE_NULL STD { int linux_inotify_rm_watch(void); }
+256 AUE_NULL STD { int linux_migrate_pages(void); }
+257 AUE_OPEN_RWTC STD { int linux_openat(l_int dfd, const char *filename, \
+ l_int flags, l_int mode); }
+258 AUE_MKDIRAT STD { int linux_mkdirat(l_int dfd, const char *pathname, \
+ l_int mode); }
+259 AUE_MKNODAT STD { int linux_mknodat(l_int dfd, const char *filename, \
+ l_int mode, l_uint dev); }
+260 AUE_FCHOWNAT STD { int linux_fchownat(l_int dfd, const char *filename, \
+ l_uid_t uid, l_gid_t gid, l_int flag); }
+261 AUE_FUTIMESAT STD { int linux_futimesat(l_int dfd, char *filename, \
+ struct l_timeval *utimes); }
+262 AUE_FSTATAT STD { int linux_newfstatat(l_int dfd, char *pathname, \
+ struct l_stat64 *statbuf, l_int flag); }
+263 AUE_UNLINKAT STD { int linux_unlinkat(l_int dfd, const char *pathname, \
+ l_int flag); }
+264 AUE_RENAMEAT STD { int linux_renameat(l_int olddfd, const char *oldname, \
+ l_int newdfd, const char *newname); }
+265 AUE_LINKAT STD { int linux_linkat(l_int olddfd, const char *oldname, \
+ l_int newdfd, const char *newname, l_int flag); }
+266 AUE_SYMLINKAT STD { int linux_symlinkat(const char *oldname, l_int newdfd, \
+ const char *newname); }
+267 AUE_READLINKAT STD { int linux_readlinkat(l_int dfd, const char *path, \
+ char *buf, l_int bufsiz); }
+268 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \
+ l_mode_t mode); }
+269 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, \
+ l_int amode); }
+270 AUE_SELECT STD { int linux_pselect6(l_int nfds, \
+ l_fd_set *readfds, l_fd_set *writefds, l_fd_set *exceptfds, \
+ struct l_timespec *tsp, l_uintptr_t *sig); }
+271 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \
+ struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); }
+272 AUE_NULL STD { int linux_unshare(void); }
+273 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \
+ l_size_t len); }
+274 AUE_NULL STD { int linux_get_robust_list(l_int pid, struct linux_robust_list_head *head, \
+ l_size_t *len); }
+275 AUE_NULL STD { int linux_splice(void); }
+276 AUE_NULL STD { int linux_tee(void); }
+277 AUE_NULL STD { int linux_sync_file_range(void); }
+278 AUE_NULL STD { int linux_vmsplice(void); }
+279 AUE_NULL STD { int linux_move_pages(void); }
+280 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \
+ const struct l_timespec *times, l_int flags); }
+281 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \
+ l_int maxevents, l_int timeout, l_sigset_t *mask); }
+282 AUE_NULL STD { int linux_signalfd(void); }
+283 AUE_NULL STD { int linux_timerfd(void); }
+284 AUE_NULL STD { int linux_eventfd(l_uint initval); }
+285 AUE_NULL STD { int linux_fallocate(l_int fd, l_int mode, \
+ l_loff_t offset, l_loff_t len); }
+286 AUE_NULL STD { int linux_timerfd_settime(void); }
+287 AUE_NULL STD { int linux_timerfd_gettime(void); }
+288 AUE_ACCEPT STD { int linux_accept4(l_int s, l_uintptr_t addr, \
+ l_uintptr_t namelen, int flags); }
+289 AUE_NULL STD { int linux_signalfd4(void); }
+290 AUE_NULL STD { int linux_eventfd2(l_uint initval, l_int flags); }
+291 AUE_NULL STD { int linux_epoll_create1(l_int flags); }
+292 AUE_NULL STD { int linux_dup3(l_int oldfd, \
+ l_int newfd, l_int flags); }
+293 AUE_NULL STD { int linux_pipe2(l_int *pipefds, l_int flags); }
+294 AUE_NULL STD { int linux_inotify_init1(void); }
+295 AUE_NULL STD { int linux_preadv(void); }
+296 AUE_NULL STD { int linux_pwritev(void); }
+297 AUE_NULL STD { int linux_rt_tsigqueueinfo(void); }
+298 AUE_NULL STD { int linux_perf_event_open(void); }
+299 AUE_NULL STD { int linux_recvmmsg(l_int s, \
+ struct l_mmsghdr *msg, l_uint vlen, \
+ l_uint flags, struct l_timespec *timeout); }
+300 AUE_NULL STD { int linux_fanotify_init(void); }
+301 AUE_NULL STD { int linux_fanotify_mark(void); }
+302 AUE_NULL STD { int linux_prlimit64(l_pid_t pid, l_uint resource, \
+ struct rlimit *new, struct rlimit *old); }
+303 AUE_NULL STD { int linux_name_to_handle_at(void); }
+304 AUE_NULL STD { int linux_open_by_handle_at(void); }
+305 AUE_NULL STD { int linux_clock_adjtime(void); }
+306 AUE_SYNC STD { int linux_syncfs(l_int fd); }
+307 AUE_NULL STD { int linux_sendmmsg(l_int s, \
+ struct l_mmsghdr *msg, l_uint vlen, \
+ l_uint flags); }
+308 AUE_NULL STD { int linux_setns(void); }
+309 AUE_NULL STD { int linux_process_vm_readv(void); }
+310 AUE_NULL STD { int linux_process_vm_writev(void); }
+311 AUE_NULL STD { int linux_kcmp(void); }
+312 AUE_NULL STD { int linux_finit_module(void); }
+; please, keep this line at the end.
+313 AUE_NULL UNIMPL nosys
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index 39c17c8d2135..e3b9f111a0a6 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -33,6 +33,7 @@
#ifndef _AMD64_LINUX_H_
#define _AMD64_LINUX_H_
+#include <compat/linux/linux.h>
#include <amd64/linux32/linux32_syscall.h>
/*
@@ -40,14 +41,12 @@
*/
extern u_char linux_debug_map[];
#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name)
-#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid
-#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid
+#define ARGS(nm, fmt) "linux(%ld/%ld): "#nm"("fmt")\n", \
+ (long)td->td_proc->p_pid, (long)td->td_tid
+#define LMSG(fmt) "linux(%ld/%ld): "fmt"\n", \
+ (long)td->td_proc->p_pid, (long)td->td_tid
#define LINUX_DTRACE linuxulator32
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_LINUX);
-#endif
-
#define LINUX32_MAXUSER ((1ul << 32) - PAGE_SIZE)
#define LINUX32_SHAREDPAGE (LINUX32_MAXUSER - PAGE_SIZE)
#define LINUX32_USRSTACK LINUX32_SHAREDPAGE
@@ -97,6 +96,7 @@ typedef l_uint l_uid_t;
typedef l_ushort l_uid16_t;
typedef l_int l_timer_t;
typedef l_int l_mqd_t;
+typedef l_ulong l_fd_mask;
typedef struct {
l_int val[2];
@@ -112,7 +112,7 @@ typedef struct {
/*
* Miscellaneous
*/
-#define LINUX_AT_COUNT 16 /* Count of used aux entry types.
+#define LINUX_AT_COUNT 20 /* Count of used aux entry types.
* Keep this synchronized with
* elf_linux_fixup() code.
*/
@@ -260,49 +260,6 @@ struct l_statfs64 {
l_int f_spare[6];
} __packed;
-/*
- * Signalling
- */
-#define LINUX_SIGHUP 1
-#define LINUX_SIGINT 2
-#define LINUX_SIGQUIT 3
-#define LINUX_SIGILL 4
-#define LINUX_SIGTRAP 5
-#define LINUX_SIGABRT 6
-#define LINUX_SIGIOT LINUX_SIGABRT
-#define LINUX_SIGBUS 7
-#define LINUX_SIGFPE 8
-#define LINUX_SIGKILL 9
-#define LINUX_SIGUSR1 10
-#define LINUX_SIGSEGV 11
-#define LINUX_SIGUSR2 12
-#define LINUX_SIGPIPE 13
-#define LINUX_SIGALRM 14
-#define LINUX_SIGTERM 15
-#define LINUX_SIGSTKFLT 16
-#define LINUX_SIGCHLD 17
-#define LINUX_SIGCONT 18
-#define LINUX_SIGSTOP 19
-#define LINUX_SIGTSTP 20
-#define LINUX_SIGTTIN 21
-#define LINUX_SIGTTOU 22
-#define LINUX_SIGURG 23
-#define LINUX_SIGXCPU 24
-#define LINUX_SIGXFSZ 25
-#define LINUX_SIGVTALRM 26
-#define LINUX_SIGPROF 27
-#define LINUX_SIGWINCH 28
-#define LINUX_SIGIO 29
-#define LINUX_SIGPOLL LINUX_SIGIO
-#define LINUX_SIGPWR 30
-#define LINUX_SIGSYS 31
-#define LINUX_SIGRTMIN 32
-
-#define LINUX_SIGTBLSZ 31
-#define LINUX_NSIG_WORDS 2
-#define LINUX_NBPW 32
-#define LINUX_NSIG (LINUX_NBPW * LINUX_NSIG_WORDS)
-
/* sigaction flags */
#define LINUX_SA_NOCLDSTOP 0x00000001
#define LINUX_SA_NOCLDWAIT 0x00000002
@@ -319,27 +276,13 @@ struct l_statfs64 {
#define LINUX_SIG_UNBLOCK 1
#define LINUX_SIG_SETMASK 2
-/* sigset_t macros */
-#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0
-#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig)
-#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig)
-
/* sigaltstack */
#define LINUX_MINSIGSTKSZ 2048
-#define LINUX_SS_ONSTACK 1
-#define LINUX_SS_DISABLE 2
-
-int linux_to_bsd_sigaltstack(int lsa);
-int bsd_to_linux_sigaltstack(int bsa);
typedef l_uintptr_t l_handler_t;
typedef l_ulong l_osigset_t;
typedef struct {
- l_uint __bits[LINUX_NSIG_WORDS];
-} __packed l_sigset_t;
-
-typedef struct {
l_handler_t lsa_handler;
l_osigset_t lsa_mask;
l_ulong lsa_flags;
@@ -508,7 +451,7 @@ struct l_sigframe {
l_int sf_sig;
struct l_sigcontext sf_sc;
struct l_fpstate sf_fpstate;
- l_uint sf_extramask[LINUX_NSIG_WORDS-1];
+ l_uint sf_extramask[1];
l_handler_t sf_handler;
} __packed;
@@ -521,50 +464,13 @@ struct l_rt_sigframe {
l_handler_t sf_handler;
} __packed;
-extern struct sysentvec elf_linux_sysvec;
-
/*
- * open/fcntl flags
+ * arch specific open/fcntl flags
*/
-#define LINUX_O_RDONLY 00000000
-#define LINUX_O_WRONLY 00000001
-#define LINUX_O_RDWR 00000002
-#define LINUX_O_ACCMODE 00000003
-#define LINUX_O_CREAT 00000100
-#define LINUX_O_EXCL 00000200
-#define LINUX_O_NOCTTY 00000400
-#define LINUX_O_TRUNC 00001000
-#define LINUX_O_APPEND 00002000
-#define LINUX_O_NONBLOCK 00004000
-#define LINUX_O_NDELAY LINUX_O_NONBLOCK
-#define LINUX_O_SYNC 00010000
-#define LINUX_FASYNC 00020000
-#define LINUX_O_DIRECT 00040000 /* Direct disk access hint */
-#define LINUX_O_LARGEFILE 00100000
-#define LINUX_O_DIRECTORY 00200000 /* Must be a directory */
-#define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */
-#define LINUX_O_NOATIME 01000000
-#define LINUX_O_CLOEXEC 02000000
-
-#define LINUX_F_DUPFD 0
-#define LINUX_F_GETFD 1
-#define LINUX_F_SETFD 2
-#define LINUX_F_GETFL 3
-#define LINUX_F_SETFL 4
-#define LINUX_F_GETLK 5
-#define LINUX_F_SETLK 6
-#define LINUX_F_SETLKW 7
-#define LINUX_F_SETOWN 8
-#define LINUX_F_GETOWN 9
-
#define LINUX_F_GETLK64 12
#define LINUX_F_SETLK64 13
#define LINUX_F_SETLKW64 14
-#define LINUX_F_RDLCK 0
-#define LINUX_F_WRLCK 1
-#define LINUX_F_UNLCK 2
-
union l_semun {
l_int val;
l_uintptr_t buf;
@@ -573,6 +479,16 @@ union l_semun {
l_uintptr_t __pad;
} __packed;
+struct l_ipc_perm {
+ l_key_t key;
+ l_uid16_t uid;
+ l_gid16_t gid;
+ l_uid16_t cuid;
+ l_gid16_t cgid;
+ l_ushort mode;
+ l_ushort seq;
+};
+
/*
* Socket defines
*/
@@ -609,22 +525,6 @@ struct l_sockaddr {
char sa_data[14];
} __packed;
-struct l_msghdr {
- l_uintptr_t msg_name;
- l_int msg_namelen;
- l_uintptr_t msg_iov;
- l_size_t msg_iovlen;
- l_uintptr_t msg_control;
- l_size_t msg_controllen;
- l_uint msg_flags;
-};
-
-struct l_cmsghdr {
- l_size_t cmsg_len;
- l_int cmsg_level;
- l_int cmsg_type;
-};
-
struct l_ifmap {
l_ulong mem_start;
l_ulong mem_end;
@@ -778,6 +678,7 @@ struct l_iovec32 {
int linux32_copyiniov(struct l_iovec32 *iovp32, l_ulong iovcnt,
struct iovec **iovp, int error);
+int linux_copyout_rusage(struct rusage *ru, void *uaddr);
/* robust futexes */
struct linux_robust_list {
diff --git a/sys/amd64/linux32/linux32_dummy.c b/sys/amd64/linux32/linux32_dummy.c
index ecf516830811..e4e9f506d0d2 100644
--- a/sys/amd64/linux32/linux32_dummy.c
+++ b/sys/amd64/linux32/linux32_dummy.c
@@ -61,7 +61,6 @@ DUMMY(bdflush);
DUMMY(sysfs);
DUMMY(query_module);
DUMMY(nfsservctl);
-DUMMY(rt_sigqueueinfo);
DUMMY(sendfile);
DUMMY(setfsuid);
DUMMY(setfsgid);
@@ -69,9 +68,6 @@ DUMMY(pivot_root);
DUMMY(mincore);
DUMMY(ptrace);
DUMMY(lookup_dcookie);
-DUMMY(epoll_create);
-DUMMY(epoll_ctl);
-DUMMY(epoll_wait);
DUMMY(remap_file_pages);
DUMMY(fstatfs64);
DUMMY(mbind);
@@ -84,7 +80,6 @@ DUMMY(mq_timedreceive);
DUMMY(mq_notify);
DUMMY(mq_getsetattr);
DUMMY(kexec_load);
-DUMMY(waitid);
/* linux 2.6.11: */
DUMMY(add_key);
DUMMY(request_key);
@@ -97,8 +92,6 @@ DUMMY(inotify_add_watch);
DUMMY(inotify_rm_watch);
/* linux 2.6.16: */
DUMMY(migrate_pages);
-DUMMY(pselect6);
-DUMMY(ppoll);
DUMMY(unshare);
/* linux 2.6.17: */
DUMMY(splice);
@@ -109,22 +102,14 @@ DUMMY(vmsplice);
DUMMY(move_pages);
/* linux 2.6.19: */
DUMMY(getcpu);
-DUMMY(epoll_pwait);
/* linux 2.6.22: */
-DUMMY(utimensat);
DUMMY(signalfd);
DUMMY(timerfd_create);
-DUMMY(eventfd);
-/* linux 2.6.23: */
-DUMMY(fallocate);
/* linux 2.6.25: */
DUMMY(timerfd_settime);
DUMMY(timerfd_gettime);
/* linux 2.6.27: */
DUMMY(signalfd4);
-DUMMY(eventfd2);
-DUMMY(epoll_create1);
-DUMMY(dup3);
DUMMY(inotify_init1);
/* linux 2.6.30: */
DUMMY(preadv);
@@ -133,17 +118,12 @@ DUMMY(pwritev);
DUMMY(rt_tsigqueueinfo);
DUMMY(perf_event_open);
/* linux 2.6.33: */
-DUMMY(recvmmsg);
DUMMY(fanotify_init);
DUMMY(fanotify_mark);
-/* linux 2.6.36: */
-DUMMY(prlimit64);
/* later: */
DUMMY(name_to_handle_at);
DUMMY(open_by_handle_at);
DUMMY(clock_adjtime);
-DUMMY(syncfs);
-DUMMY(sendmmsg);
DUMMY(setns);
DUMMY(process_vm_readv);
DUMMY(process_vm_writev);
diff --git a/sys/amd64/linux32/linux32_genassym.c b/sys/amd64/linux32/linux32_genassym.c
index a022fac17589..bc94139c226d 100644
--- a/sys/amd64/linux32/linux32_genassym.c
+++ b/sys/amd64/linux32/linux32_genassym.c
@@ -3,12 +3,16 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/assym.h>
+#include <sys/resource.h>
#include <sys/systm.h>
#include <amd64/linux32/linux.h>
+#include <compat/linux/linux_mib.h>
ASSYM(LINUX_SIGF_HANDLER, offsetof(struct l_sigframe, sf_handler));
ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc));
ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler));
ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc));
ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext));
+ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE);
+ASSYM(LINUX_SC_ESP, offsetof(struct l_sigcontext, sc_esp));
diff --git a/sys/amd64/linux32/linux32_locore.s b/sys/amd64/linux32/linux32_locore.s
index 36e1abf87b83..4edbdf3db630 100644
--- a/sys/amd64/linux32/linux32_locore.s
+++ b/sys/amd64/linux32/linux32_locore.s
@@ -5,34 +5,152 @@
#include <amd64/linux32/linux32_syscall.h> /* system call numbers */
+.data
+
+ .globl linux_platform
+linux_platform:
+ .asciz "i686"
+
.text
.code32
-NON_GPROF_ENTRY(linux_sigcode)
- call *LINUX_SIGF_HANDLER(%esp)
- leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */
- movl %esp, %ebx /* pass sigframe */
- push %eax /* fake ret addr */
+/*
+ * To avoid excess stack frame the signal trampoline code emulates
+ * the 'call' instruction.
+ */
+NON_GPROF_ENTRY(linux32_sigcode)
+ movl %esp, %ebx /* preserve sigframe */
+ call .getip0
+.getip0:
+ popl %eax
+ add $.startsigcode-.getip0, %eax /* ret address */
+ push %eax
+ jmp *LINUX_SIGF_HANDLER(%ebx)
+.startsigcode:
+ popl %eax
movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
int $0x80 /* enter kernel with args */
+.endsigcode:
0: jmp 0b
- ALIGN_TEXT
-/* XXXXX */
-linux_rt_sigcode:
- call *LINUX_RT_SIGF_HANDLER(%esp)
+
+NON_GPROF_ENTRY(linux32_rt_sigcode)
leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */
leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */
- push %eax /* fake ret addr */
+ movl %esp, %edi
+ call .getip1
+.getip1:
+ popl %eax
+ add $.startrtsigcode-.getip1, %eax /* ret address */
+ push %eax
+ jmp *LINUX_RT_SIGF_HANDLER(%edi)
+.startrtsigcode:
movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */
int $0x80 /* enter kernel with args */
+.endrtsigcode:
0: jmp 0b
- ALIGN_TEXT
-/* XXXXX */
-linux_esigcode:
-
- .data
- .globl linux_szsigcode, linux_sznonrtsigcode
-linux_szsigcode:
- .long linux_esigcode-linux_sigcode
-linux_sznonrtsigcode:
- .long linux_rt_sigcode-linux_sigcode
+
+NON_GPROF_ENTRY(linux32_vsyscall)
+.startvsyscall:
+ int $0x80
+ ret
+.endvsyscall:
+
+#if 0
+ .section .note.Linux, "a",@note
+ .long 2f - 1f /* namesz */
+ .balign 4
+ .long 4f - 3f /* descsz */
+ .long 0
+1:
+ .asciz "Linux"
+2:
+ .balign 4
+3:
+ .long LINUX_VERSION_CODE
+4:
+ .balign 4
+ .previous
+#endif
+
+#define do_cfa_expr(offset) \
+ .byte 0x0f; /* DW_CFA_def_cfa_expression */ \
+ .uleb128 11f-10f; /* length */ \
+10: .byte 0x74; /* DW_OP_breg4 */ \
+ .sleb128 offset; /* offset */ \
+ .byte 0x06; /* DW_OP_deref */ \
+11:
+
+
+ /* CIE */
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAMEDLSI1:
+ .long .LENDCIEDLSI1-.LSTARTCIEDLSI1
+.LSTARTCIEDLSI1:
+ .long 0 /* CIE ID */
+ .byte 1 /* Version number */
+ .string "zRS" /* NULL-terminated
+ * augmentation string
+ */
+ .uleb128 1 /* Code alignment factor */
+ .sleb128 -4 /* Data alignment factor */
+ .byte 8 /* Return address
+ * register column
+ */
+ .uleb128 1 /* Augmentation value length */
+ .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
+ .byte 0 /* DW_CFA_nop */
+ .align 4
+.LENDCIEDLSI1:
+
+ /* FDE */
+ .long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */
+.LSTARTFDEDLSI1:
+ .long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */
+ .long .startsigcode-. /* PC-relative start address */
+ .long .endsigcode-.startsigcode
+ .uleb128 0 /* Augmentation */
+ do_cfa_expr(LINUX_SIGF_SC-8)
+ .align 4
+.LENDFDEDLSI1:
+
+ .long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */
+.LSTARTFDEDLSI2:
+ .long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */
+ .long .startrtsigcode-. /* PC-relative start address */
+ .long .endrtsigcode-.startrtsigcode
+ .uleb128 0 /* Augmentation */
+ do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP)
+ .align 4
+.LENDFDEDLSI2:
+ .previous
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAMEDLSI2:
+ .long .LENDCIEDLSI2-.LSTARTCIEDLSI2
+.LSTARTCIEDLSI2:
+ .long 0 /* CIE ID */
+ .byte 1 /* Version number */
+ .string "zR" /* NULL-terminated
+ * augmentation string
+ */
+ .uleb128 1 /* Code alignment factor */
+ .sleb128 -4 /* Data alignment factor */
+ .byte 8 /* Return address register column */
+ .uleb128 1 /* Augmentation value length */
+ .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
+ .byte 0x0c /* DW_CFA_def_cfa */
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .uleb128 1
+ .align 4
+.LENDCIEDLSI2:
+ .long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */
+.LSTARTFDEDLSI3:
+ .long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */
+ .long .startvsyscall-. /* PC-relative start address */
+ .long .endvsyscall-.startvsyscall
+ .uleb128 0
+ .align 4
+.LENDFDEDLSI3:
+ .previous
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 155e90b1f4ba..1c54c5c87430 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -31,6 +31,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_compat.h"
+
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -48,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
-#include <sys/sched.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/unistd.h>
@@ -73,6 +74,8 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_util.h>
#include <compat/linux/linux_emul.h>
+static void bsd_to_linux_rusage(struct rusage *ru, struct l_rusage *lru);
+
struct l_old_select_argv {
l_int nfds;
l_uintptr_t readfds;
@@ -81,34 +84,10 @@ struct l_old_select_argv {
l_uintptr_t timeout;
} __packed;
-int
-linux_to_bsd_sigaltstack(int lsa)
-{
- int bsa = 0;
-
- if (lsa & LINUX_SS_DISABLE)
- bsa |= SS_DISABLE;
- if (lsa & LINUX_SS_ONSTACK)
- bsa |= SS_ONSTACK;
- return (bsa);
-}
-
static int linux_mmap_common(struct thread *td, l_uintptr_t addr,
l_size_t len, l_int prot, l_int flags, l_int fd,
l_loff_t pos);
-int
-bsd_to_linux_sigaltstack(int bsa)
-{
- int lsa = 0;
-
- if (bsa & SS_DISABLE)
- lsa |= LINUX_SS_DISABLE;
- if (bsa & SS_ONSTACK)
- lsa |= LINUX_SS_ONSTACK;
- return (lsa);
-}
-
static void
bsd_to_linux_rusage(struct rusage *ru, struct l_rusage *lru)
{
@@ -134,10 +113,19 @@ bsd_to_linux_rusage(struct rusage *ru, struct l_rusage *lru)
}
int
+linux_copyout_rusage(struct rusage *ru, void *uaddr)
+{
+ struct l_rusage lru;
+
+ bsd_to_linux_rusage(ru, &lru);
+
+ return (copyout(&lru, uaddr, sizeof(struct l_rusage)));
+}
+
+int
linux_execve(struct thread *td, struct linux_execve_args *args)
{
struct image_args eargs;
- struct vmspace *oldvmspace;
char *path;
int error;
@@ -148,26 +136,11 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
printf(ARGS(execve, "%s"), path);
#endif
- error = pre_execve(td, &oldvmspace);
- if (error != 0) {
- free(path, M_TEMP);
- return (error);
- }
error = freebsd32_exec_copyin_args(&eargs, path, UIO_SYSSPACE,
args->argp, args->envp);
free(path, M_TEMP);
if (error == 0)
- error = kern_execve(td, &eargs, NULL);
- if (error == 0) {
- /* Linux process can execute FreeBSD one, do not attempt
- * to create emuldata for such process using
- * linux_proc_init, this leads to a panic on KASSERT
- * because such process has p->p_emuldata == NULL.
- */
- if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX)
- error = linux_proc_init(td, 0, 0);
- }
- post_execve(td, error, oldvmspace);
+ error = linux_common_execve(td, &eargs);
return (error);
}
@@ -465,8 +438,14 @@ int
linux_set_upcall_kse(struct thread *td, register_t stack)
{
- td->td_frame->tf_rsp = stack;
+ if (stack)
+ td->td_frame->tf_rsp = stack;
+ /*
+ * The newly created Linux thread returns
+ * to the user space by the same path that a parent do.
+ */
+ td->td_frame->tf_rax = 0;
return (0);
}
@@ -636,7 +615,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot,
*/
PROC_LOCK(p);
p->p_vmspace->vm_maxsaddr = (char *)LINUX32_USRSTACK -
- lim_cur(p, RLIMIT_STACK);
+ lim_cur_proc(p, RLIMIT_STACK);
PROC_UNLOCK(p);
}
@@ -729,7 +708,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
act.lsa_flags = osa.lsa_flags;
act.lsa_restorer = osa.lsa_restorer;
LINUX_SIGEMPTYSET(act.lsa_mask);
- act.lsa_mask.__bits[0] = osa.lsa_mask;
+ act.lsa_mask.__mask = osa.lsa_mask;
}
error = linux_do_sigaction(td, args->sig, args->nsa ? &act : NULL,
@@ -739,7 +718,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
osa.lsa_handler = oact.lsa_handler;
osa.lsa_flags = oact.lsa_flags;
osa.lsa_restorer = oact.lsa_restorer;
- osa.lsa_mask = oact.lsa_mask.__bits[0];
+ osa.lsa_mask = oact.lsa_mask.__mask;
error = copyout(&osa, args->osa, sizeof(l_osigaction_t));
}
@@ -763,7 +742,7 @@ linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args)
#endif
LINUX_SIGEMPTYSET(mask);
- mask.__bits[0] = args->mask;
+ mask.__mask = args->mask;
linux_to_bsd_sigset(&mask, &sigmask);
return (kern_sigsuspend(td, sigmask));
}
@@ -910,37 +889,18 @@ linux_settimeofday(struct thread *td, struct linux_settimeofday_args *uap)
int
linux_getrusage(struct thread *td, struct linux_getrusage_args *uap)
{
- struct l_rusage s32;
struct rusage s;
int error;
error = kern_getrusage(td, uap->who, &s);
if (error != 0)
return (error);
- if (uap->rusage != NULL) {
- bsd_to_linux_rusage(&s, &s32);
- error = copyout(&s32, uap->rusage, sizeof(s32));
- }
+ if (uap->rusage != NULL)
+ error = linux_copyout_rusage(&s, uap->rusage);
return (error);
}
int
-linux_sched_rr_get_interval(struct thread *td,
- struct linux_sched_rr_get_interval_args *uap)
-{
- struct timespec ts;
- struct l_timespec ts32;
- int error;
-
- error = kern_sched_rr_get_interval(td, uap->pid, &ts);
- if (error != 0)
- return (error);
- ts32.tv_sec = ts.tv_sec;
- ts32.tv_nsec = ts.tv_nsec;
- return (copyout(&ts32, uap->interval, sizeof(ts32)));
-}
-
-int
linux_set_thread_area(struct thread *td,
struct linux_set_thread_area_args *args)
{
@@ -1042,37 +1002,3 @@ linux_set_thread_area(struct thread *td,
return (0);
}
-
-int
-linux_wait4(struct thread *td, struct linux_wait4_args *args)
-{
- int error, options;
- struct rusage ru, *rup;
- struct l_rusage lru;
-
-#ifdef DEBUG
- if (ldebug(wait4))
- printf(ARGS(wait4, "%d, %p, %d, %p"),
- args->pid, (void *)args->status, args->options,
- (void *)args->rusage);
-#endif
-
- options = (args->options & (WNOHANG | WUNTRACED));
- /* WLINUXCLONE should be equal to __WCLONE, but we make sure */
- if (args->options & __WCLONE)
- options |= WLINUXCLONE;
-
- if (args->rusage != NULL)
- rup = &ru;
- else
- rup = NULL;
- error = linux_common_wait(td, args->pid, args->status, options, rup);
- if (error)
- return (error);
- if (args->rusage != NULL) {
- bsd_to_linux_rusage(rup, &lru);
- error = copyout(&lru, args->rusage, sizeof(lru));
- }
-
- return (error);
-}
diff --git a/sys/amd64/linux32/linux32_proto.h b/sys/amd64/linux32/linux32_proto.h
index fd6b5420afcc..c6b233e2915a 100644
--- a/sys/amd64/linux32/linux32_proto.h
+++ b/sys/amd64/linux32/linux32_proto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/amd64/linux32/syscalls.master 276508 2015-01-01 18:37:03Z dchagin
+ * created from FreeBSD: head/sys/amd64/linux32/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
*/
#ifndef _LINUX_SYSPROTO_H_
@@ -35,6 +35,9 @@ struct thread;
#endif
#define nosys linux_nosys
+struct linux_exit_args {
+ char rval_l_[PADL_(int)]; int rval; char rval_r_[PADR_(int)];
+};
struct linux_fork_args {
register_t dummy;
};
@@ -475,6 +478,14 @@ struct linux_fdatasync_args {
struct linux_sysctl_args {
char args_l_[PADL_(struct l___sysctl_args *)]; struct l___sysctl_args * args; char args_r_[PADR_(struct l___sysctl_args *)];
};
+struct linux_sched_setparam_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)];
+};
+struct linux_sched_getparam_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)];
+};
struct linux_sched_setscheduler_args {
char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
@@ -563,7 +574,9 @@ struct linux_rt_sigtimedwait_args {
char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
};
struct linux_rt_sigqueueinfo_args {
- register_t dummy;
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
+ char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)];
};
struct linux_rt_sigsuspend_args {
char newset_l_[PADL_(l_sigset_t *)]; l_sigset_t * newset; char newset_r_[PADR_(l_sigset_t *)];
@@ -766,13 +779,19 @@ struct linux_lookup_dcookie_args {
register_t dummy;
};
struct linux_epoll_create_args {
- register_t dummy;
+ char size_l_[PADL_(l_int)]; l_int size; char size_r_[PADR_(l_int)];
};
struct linux_epoll_ctl_args {
- register_t dummy;
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char op_l_[PADL_(l_int)]; l_int op; char op_r_[PADR_(l_int)];
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char event_l_[PADL_(struct epoll_event *)]; struct epoll_event * event; char event_r_[PADR_(struct epoll_event *)];
};
struct linux_epoll_wait_args {
- register_t dummy;
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)];
+ char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)];
+ char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)];
};
struct linux_remap_file_pages_args {
register_t dummy;
@@ -873,7 +892,11 @@ struct linux_kexec_load_args {
register_t dummy;
};
struct linux_waitid_args {
- register_t dummy;
+ char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)];
+ char id_l_[PADL_(l_pid_t)]; l_pid_t id; char id_r_[PADR_(l_pid_t)];
+ char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)];
+ char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)];
+ char rusage_l_[PADL_(struct l_rusage *)]; struct l_rusage * rusage; char rusage_r_[PADR_(struct l_rusage *)];
};
struct linux_add_key_args {
register_t dummy;
@@ -975,13 +998,21 @@ struct linux_faccessat_args {
char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)];
char amode_l_[PADL_(l_int)]; l_int amode; char amode_r_[PADR_(l_int)];
- char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)];
};
struct linux_pselect6_args {
- register_t dummy;
+ char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)];
+ char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)];
+ char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)];
+ char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)];
+ char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)];
+ char sig_l_[PADL_(l_uintptr_t *)]; l_uintptr_t * sig; char sig_r_[PADR_(l_uintptr_t *)];
};
struct linux_ppoll_args {
- register_t dummy;
+ char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)];
+ char nfds_l_[PADL_(uint32_t)]; uint32_t nfds; char nfds_r_[PADR_(uint32_t)];
+ char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)];
+ char sset_l_[PADL_(l_sigset_t *)]; l_sigset_t * sset; char sset_r_[PADR_(l_sigset_t *)];
+ char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)];
};
struct linux_unshare_args {
register_t dummy;
@@ -1014,10 +1045,17 @@ struct linux_getcpu_args {
register_t dummy;
};
struct linux_epoll_pwait_args {
- register_t dummy;
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)];
+ char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)];
+ char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)];
+ char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
};
struct linux_utimensat_args {
- register_t dummy;
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)];
+ char times_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * times; char times_r_[PADR_(const struct l_timespec *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_signalfd_args {
register_t dummy;
@@ -1026,10 +1064,13 @@ struct linux_timerfd_create_args {
register_t dummy;
};
struct linux_eventfd_args {
- register_t dummy;
+ char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)];
};
struct linux_fallocate_args {
- register_t dummy;
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+ char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+ char len_l_[PADL_(l_loff_t)]; l_loff_t len; char len_r_[PADR_(l_loff_t)];
};
struct linux_timerfd_settime_args {
register_t dummy;
@@ -1041,13 +1082,16 @@ struct linux_signalfd4_args {
register_t dummy;
};
struct linux_eventfd2_args {
- register_t dummy;
+ char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_epoll_create1_args {
- register_t dummy;
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_dup3_args {
- register_t dummy;
+ char oldfd_l_[PADL_(l_int)]; l_int oldfd; char oldfd_r_[PADR_(l_int)];
+ char newfd_l_[PADL_(l_int)]; l_int newfd; char newfd_r_[PADR_(l_int)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_pipe2_args {
char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)];
@@ -1069,7 +1113,11 @@ struct linux_perf_event_open_args {
register_t dummy;
};
struct linux_recvmmsg_args {
- register_t dummy;
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)];
+ char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
+ char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
};
struct linux_fanotify_init_args {
register_t dummy;
@@ -1078,7 +1126,10 @@ struct linux_fanotify_mark_args {
register_t dummy;
};
struct linux_prlimit64_args {
- register_t dummy;
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)];
+ char new_l_[PADL_(struct rlimit *)]; struct rlimit * new; char new_r_[PADR_(struct rlimit *)];
+ char old_l_[PADL_(struct rlimit *)]; struct rlimit * old; char old_r_[PADR_(struct rlimit *)];
};
struct linux_name_to_handle_at_args {
register_t dummy;
@@ -1090,10 +1141,13 @@ struct linux_clock_adjtime_args {
register_t dummy;
};
struct linux_syncfs_args {
- register_t dummy;
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
};
struct linux_sendmmsg_args {
- register_t dummy;
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)];
+ char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
};
struct linux_setns_args {
register_t dummy;
@@ -1105,6 +1159,7 @@ struct linux_process_vm_writev_args {
register_t dummy;
};
#define nosys linux_nosys
+int linux_exit(struct thread *, struct linux_exit_args *);
int linux_fork(struct thread *, struct linux_fork_args *);
int linux_open(struct thread *, struct linux_open_args *);
int linux_waitpid(struct thread *, struct linux_waitpid_args *);
@@ -1216,6 +1271,8 @@ int linux_writev(struct thread *, struct linux_writev_args *);
int linux_getsid(struct thread *, struct linux_getsid_args *);
int linux_fdatasync(struct thread *, struct linux_fdatasync_args *);
int linux_sysctl(struct thread *, struct linux_sysctl_args *);
+int linux_sched_setparam(struct thread *, struct linux_sched_setparam_args *);
+int linux_sched_getparam(struct thread *, struct linux_sched_getparam_args *);
int linux_sched_setscheduler(struct thread *, struct linux_sched_setscheduler_args *);
int linux_sched_getscheduler(struct thread *, struct linux_sched_getscheduler_args *);
int linux_sched_get_priority_max(struct thread *, struct linux_sched_get_priority_max_args *);
@@ -1407,6 +1464,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#endif /* COMPAT_FREEBSD7 */
+#define LINUX_SYS_AUE_linux_exit AUE_EXIT
#define LINUX_SYS_AUE_linux_fork AUE_FORK
#define LINUX_SYS_AUE_linux_open AUE_OPEN_RWTC
#define LINUX_SYS_AUE_linux_waitpid AUE_WAIT4
@@ -1518,6 +1576,8 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_getsid AUE_GETSID
#define LINUX_SYS_AUE_linux_fdatasync AUE_NULL
#define LINUX_SYS_AUE_linux_sysctl AUE_SYSCTL
+#define LINUX_SYS_AUE_linux_sched_setparam AUE_SCHED_SETPARAM
+#define LINUX_SYS_AUE_linux_sched_getparam AUE_SCHED_GETPARAM
#define LINUX_SYS_AUE_linux_sched_setscheduler AUE_SCHED_SETSCHEDULER
#define LINUX_SYS_AUE_linux_sched_getscheduler AUE_SCHED_GETSCHEDULER
#define LINUX_SYS_AUE_linux_sched_get_priority_max AUE_SCHED_GET_PRIORITY_MAX
@@ -1617,7 +1677,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_mq_notify AUE_NULL
#define LINUX_SYS_AUE_linux_mq_getsetattr AUE_NULL
#define LINUX_SYS_AUE_linux_kexec_load AUE_NULL
-#define LINUX_SYS_AUE_linux_waitid AUE_NULL
+#define LINUX_SYS_AUE_linux_waitid AUE_WAIT6
#define LINUX_SYS_AUE_linux_add_key AUE_NULL
#define LINUX_SYS_AUE_linux_request_key AUE_NULL
#define LINUX_SYS_AUE_linux_keyctl AUE_NULL
@@ -1640,8 +1700,8 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_readlinkat AUE_READLINKAT
#define LINUX_SYS_AUE_linux_fchmodat AUE_FCHMODAT
#define LINUX_SYS_AUE_linux_faccessat AUE_FACCESSAT
-#define LINUX_SYS_AUE_linux_pselect6 AUE_NULL
-#define LINUX_SYS_AUE_linux_ppoll AUE_NULL
+#define LINUX_SYS_AUE_linux_pselect6 AUE_SELECT
+#define LINUX_SYS_AUE_linux_ppoll AUE_POLL
#define LINUX_SYS_AUE_linux_unshare AUE_NULL
#define LINUX_SYS_AUE_linux_set_robust_list AUE_NULL
#define LINUX_SYS_AUE_linux_get_robust_list AUE_NULL
@@ -1652,7 +1712,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_move_pages AUE_NULL
#define LINUX_SYS_AUE_linux_getcpu AUE_NULL
#define LINUX_SYS_AUE_linux_epoll_pwait AUE_NULL
-#define LINUX_SYS_AUE_linux_utimensat AUE_NULL
+#define LINUX_SYS_AUE_linux_utimensat AUE_FUTIMESAT
#define LINUX_SYS_AUE_linux_signalfd AUE_NULL
#define LINUX_SYS_AUE_linux_timerfd_create AUE_NULL
#define LINUX_SYS_AUE_linux_eventfd AUE_NULL
@@ -1676,7 +1736,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_name_to_handle_at AUE_NULL
#define LINUX_SYS_AUE_linux_open_by_handle_at AUE_NULL
#define LINUX_SYS_AUE_linux_clock_adjtime AUE_NULL
-#define LINUX_SYS_AUE_linux_syncfs AUE_NULL
+#define LINUX_SYS_AUE_linux_syncfs AUE_SYNC
#define LINUX_SYS_AUE_linux_sendmmsg AUE_NULL
#define LINUX_SYS_AUE_linux_setns AUE_NULL
#define LINUX_SYS_AUE_linux_process_vm_readv AUE_NULL
diff --git a/sys/amd64/linux32/linux32_syscall.h b/sys/amd64/linux32/linux32_syscall.h
index 01fd99a88995..f2410f3a726d 100644
--- a/sys/amd64/linux32/linux32_syscall.h
+++ b/sys/amd64/linux32/linux32_syscall.h
@@ -3,10 +3,10 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/amd64/linux32/syscalls.master 276508 2015-01-01 18:37:03Z dchagin
+ * created from FreeBSD: head/sys/amd64/linux32/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
*/
-#define LINUX_SYS_exit 1
+#define LINUX_SYS_linux_exit 1
#define LINUX_SYS_linux_fork 2
#define LINUX_SYS_read 3
#define LINUX_SYS_write 4
@@ -143,8 +143,8 @@
#define LINUX_SYS_munlock 151
#define LINUX_SYS_mlockall 152
#define LINUX_SYS_munlockall 153
-#define LINUX_SYS_sched_setparam 154
-#define LINUX_SYS_sched_getparam 155
+#define LINUX_SYS_linux_sched_setparam 154
+#define LINUX_SYS_linux_sched_getparam 155
#define LINUX_SYS_linux_sched_setscheduler 156
#define LINUX_SYS_linux_sched_getscheduler 157
#define LINUX_SYS_sched_yield 158
@@ -321,4 +321,4 @@
#define LINUX_SYS_linux_setns 346
#define LINUX_SYS_linux_process_vm_readv 347
#define LINUX_SYS_linux_process_vm_writev 348
-#define LINUX_SYS_MAXSYSCALL 349
+#define LINUX_SYS_MAXSYSCALL 350
diff --git a/sys/amd64/linux32/linux32_syscalls.c b/sys/amd64/linux32/linux32_syscalls.c
index cb8045892af1..6f26207c2fd2 100644
--- a/sys/amd64/linux32/linux32_syscalls.c
+++ b/sys/amd64/linux32/linux32_syscalls.c
@@ -3,13 +3,13 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/amd64/linux32/syscalls.master 276508 2015-01-01 18:37:03Z dchagin
+ * created from FreeBSD: head/sys/amd64/linux32/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
*/
const char *linux_syscallnames[] = {
#define nosys linux_nosys
"#0", /* 0 = setup */
- "exit", /* 1 = exit */
+ "linux_exit", /* 1 = linux_exit */
"linux_fork", /* 2 = linux_fork */
"read", /* 3 = read */
"write", /* 4 = write */
@@ -162,8 +162,8 @@ const char *linux_syscallnames[] = {
"munlock", /* 151 = munlock */
"mlockall", /* 152 = mlockall */
"munlockall", /* 153 = munlockall */
- "sched_setparam", /* 154 = sched_setparam */
- "sched_getparam", /* 155 = sched_getparam */
+ "linux_sched_setparam", /* 154 = linux_sched_setparam */
+ "linux_sched_getparam", /* 155 = linux_sched_getparam */
"linux_sched_setscheduler", /* 156 = linux_sched_setscheduler */
"linux_sched_getscheduler", /* 157 = linux_sched_getscheduler */
"sched_yield", /* 158 = sched_yield */
@@ -357,4 +357,5 @@ const char *linux_syscallnames[] = {
"linux_setns", /* 346 = linux_setns */
"linux_process_vm_readv", /* 347 = linux_process_vm_readv */
"linux_process_vm_writev", /* 348 = linux_process_vm_writev */
+ "#349", /* 349 = nosys */
};
diff --git a/sys/amd64/linux32/linux32_sysent.c b/sys/amd64/linux32/linux32_sysent.c
index 4fee146d43b8..004b886936e0 100644
--- a/sys/amd64/linux32/linux32_sysent.c
+++ b/sys/amd64/linux32/linux32_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/amd64/linux32/syscalls.master 276508 2015-01-01 18:37:03Z dchagin
+ * created from FreeBSD: head/sys/amd64/linux32/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
*/
#include "opt_compat.h"
@@ -20,7 +20,7 @@
struct sysent linux_sysent[] = {
#define nosys linux_nosys
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 0 = setup */
- { AS(sys_exit_args), (sy_call_t *)sys_sys_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = exit */
+ { AS(linux_exit_args), (sy_call_t *)linux_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = linux_exit */
{ 0, (sy_call_t *)linux_fork, AUE_FORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 2 = linux_fork */
{ AS(read_args), (sy_call_t *)sys_read, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 3 = read */
{ AS(write_args), (sy_call_t *)sys_write, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 4 = write */
@@ -173,8 +173,8 @@ struct sysent linux_sysent[] = {
{ AS(munlock_args), (sy_call_t *)sys_munlock, AUE_MUNLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 151 = munlock */
{ AS(mlockall_args), (sy_call_t *)sys_mlockall, AUE_MLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 152 = mlockall */
{ 0, (sy_call_t *)sys_munlockall, AUE_MUNLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 153 = munlockall */
- { AS(sched_setparam_args), (sy_call_t *)sys_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 154 = sched_setparam */
- { AS(sched_getparam_args), (sy_call_t *)sys_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = sched_getparam */
+ { AS(linux_sched_setparam_args), (sy_call_t *)linux_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 154 = linux_sched_setparam */
+ { AS(linux_sched_getparam_args), (sy_call_t *)linux_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = linux_sched_getparam */
{ AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler, AUE_SCHED_SETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 156 = linux_sched_setscheduler */
{ AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler, AUE_SCHED_GETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 157 = linux_sched_getscheduler */
{ 0, (sy_call_t *)sys_sched_yield, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 158 = sched_yield */
@@ -197,7 +197,7 @@ struct sysent linux_sysent[] = {
{ AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 175 = linux_rt_sigprocmask */
{ AS(linux_rt_sigpending_args), (sy_call_t *)linux_rt_sigpending, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 176 = linux_rt_sigpending */
{ AS(linux_rt_sigtimedwait_args), (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 177 = linux_rt_sigtimedwait */
- { 0, (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_rt_sigqueueinfo */
+ { AS(linux_rt_sigqueueinfo_args), (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_rt_sigqueueinfo */
{ AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 179 = linux_rt_sigsuspend */
{ AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_PREAD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 180 = linux_pread */
{ AS(linux_pwrite_args), (sy_call_t *)linux_pwrite, AUE_PWRITE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 181 = linux_pwrite */
@@ -273,9 +273,9 @@ struct sysent linux_sysent[] = {
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 251 = */
{ AS(linux_exit_group_args), (sy_call_t *)linux_exit_group, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 252 = linux_exit_group */
{ 0, (sy_call_t *)linux_lookup_dcookie, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 253 = linux_lookup_dcookie */
- { 0, (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_epoll_create */
- { 0, (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_epoll_ctl */
- { 0, (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_epoll_wait */
+ { AS(linux_epoll_create_args), (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_epoll_create */
+ { AS(linux_epoll_ctl_args), (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_epoll_ctl */
+ { AS(linux_epoll_wait_args), (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_epoll_wait */
{ 0, (sy_call_t *)linux_remap_file_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 257 = linux_remap_file_pages */
{ AS(linux_set_tid_address_args), (sy_call_t *)linux_set_tid_address, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 258 = linux_set_tid_address */
{ AS(linux_timer_create_args), (sy_call_t *)linux_timer_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 259 = linux_timer_create */
@@ -303,7 +303,7 @@ struct sysent linux_sysent[] = {
{ 0, (sy_call_t *)linux_mq_notify, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 281 = linux_mq_notify */
{ 0, (sy_call_t *)linux_mq_getsetattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 282 = linux_mq_getsetattr */
{ 0, (sy_call_t *)linux_kexec_load, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 283 = linux_kexec_load */
- { 0, (sy_call_t *)linux_waitid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_waitid */
+ { AS(linux_waitid_args), (sy_call_t *)linux_waitid, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_waitid */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 285 = */
{ 0, (sy_call_t *)linux_add_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 286 = linux_add_key */
{ 0, (sy_call_t *)linux_request_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 287 = linux_request_key */
@@ -327,8 +327,8 @@ struct sysent linux_sysent[] = {
{ AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_READLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 305 = linux_readlinkat */
{ AS(linux_fchmodat_args), (sy_call_t *)linux_fchmodat, AUE_FCHMODAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 306 = linux_fchmodat */
{ AS(linux_faccessat_args), (sy_call_t *)linux_faccessat, AUE_FACCESSAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 307 = linux_faccessat */
- { 0, (sy_call_t *)linux_pselect6, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_pselect6 */
- { 0, (sy_call_t *)linux_ppoll, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_ppoll */
+ { AS(linux_pselect6_args), (sy_call_t *)linux_pselect6, AUE_SELECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_pselect6 */
+ { AS(linux_ppoll_args), (sy_call_t *)linux_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_ppoll */
{ 0, (sy_call_t *)linux_unshare, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 310 = linux_unshare */
{ AS(linux_set_robust_list_args), (sy_call_t *)linux_set_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 311 = linux_set_robust_list */
{ AS(linux_get_robust_list_args), (sy_call_t *)linux_get_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 312 = linux_get_robust_list */
@@ -338,34 +338,35 @@ struct sysent linux_sysent[] = {
{ 0, (sy_call_t *)linux_vmsplice, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 316 = linux_vmsplice */
{ 0, (sy_call_t *)linux_move_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 317 = linux_move_pages */
{ 0, (sy_call_t *)linux_getcpu, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 318 = linux_getcpu */
- { 0, (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 319 = linux_epoll_pwait */
- { 0, (sy_call_t *)linux_utimensat, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 320 = linux_utimensat */
+ { AS(linux_epoll_pwait_args), (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 319 = linux_epoll_pwait */
+ { AS(linux_utimensat_args), (sy_call_t *)linux_utimensat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 320 = linux_utimensat */
{ 0, (sy_call_t *)linux_signalfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 321 = linux_signalfd */
{ 0, (sy_call_t *)linux_timerfd_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 322 = linux_timerfd_create */
- { 0, (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 323 = linux_eventfd */
- { 0, (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 324 = linux_fallocate */
+ { AS(linux_eventfd_args), (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 323 = linux_eventfd */
+ { AS(linux_fallocate_args), (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 324 = linux_fallocate */
{ 0, (sy_call_t *)linux_timerfd_settime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 325 = linux_timerfd_settime */
{ 0, (sy_call_t *)linux_timerfd_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 326 = linux_timerfd_gettime */
{ 0, (sy_call_t *)linux_signalfd4, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 327 = linux_signalfd4 */
- { 0, (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */
- { 0, (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */
- { 0, (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */
+ { AS(linux_eventfd2_args), (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */
+ { AS(linux_epoll_create1_args), (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */
+ { AS(linux_dup3_args), (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */
{ AS(linux_pipe2_args), (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 331 = linux_pipe2 */
{ 0, (sy_call_t *)linux_inotify_init1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 332 = linux_inotify_init1 */
{ 0, (sy_call_t *)linux_preadv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 333 = linux_preadv */
{ 0, (sy_call_t *)linux_pwritev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 334 = linux_pwritev */
{ 0, (sy_call_t *)linux_rt_tsigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 335 = linux_rt_tsigqueueinfo */
{ 0, (sy_call_t *)linux_perf_event_open, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 336 = linux_perf_event_open */
- { 0, (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = linux_recvmmsg */
+ { AS(linux_recvmmsg_args), (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = linux_recvmmsg */
{ 0, (sy_call_t *)linux_fanotify_init, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 338 = linux_fanotify_init */
{ 0, (sy_call_t *)linux_fanotify_mark, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 339 = linux_fanotify_mark */
- { 0, (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 340 = linux_prlimit64 */
+ { AS(linux_prlimit64_args), (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 340 = linux_prlimit64 */
{ 0, (sy_call_t *)linux_name_to_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 341 = linux_name_to_handle_at */
{ 0, (sy_call_t *)linux_open_by_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 342 = linux_open_by_handle_at */
{ 0, (sy_call_t *)linux_clock_adjtime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 343 = linux_clock_adjtime */
- { 0, (sy_call_t *)linux_syncfs, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 344 = linux_syncfs */
- { 0, (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 345 = linux_sendmmsg */
+ { AS(linux_syncfs_args), (sy_call_t *)linux_syncfs, AUE_SYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 344 = linux_syncfs */
+ { AS(linux_sendmmsg_args), (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 345 = linux_sendmmsg */
{ 0, (sy_call_t *)linux_setns, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 346 = linux_setns */
{ 0, (sy_call_t *)linux_process_vm_readv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 347 = linux_process_vm_readv */
{ 0, (sy_call_t *)linux_process_vm_writev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 348 = linux_process_vm_writev */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 349 = nosys */
};
diff --git a/sys/amd64/linux32/linux32_systrace_args.c b/sys/amd64/linux32/linux32_systrace_args.c
index 2d563acc4180..b6ccd334178f 100644
--- a/sys/amd64/linux32/linux32_systrace_args.c
+++ b/sys/amd64/linux32/linux32_systrace_args.c
@@ -12,9 +12,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
int64_t *iarg = (int64_t *) uarg;
switch (sysnum) {
#define nosys linux_nosys
- /* sys_exit */
+ /* linux_exit */
case 1: {
- struct sys_exit_args *p = params;
+ struct linux_exit_args *p = params;
iarg[0] = p->rval; /* int */
*n_args = 1;
break;
@@ -1043,19 +1043,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 0;
break;
}
- /* sched_setparam */
+ /* linux_sched_setparam */
case 154: {
- struct sched_setparam_args *p = params;
- iarg[0] = p->pid; /* pid_t */
- uarg[1] = (intptr_t) p->param; /* const struct sched_param * */
+ struct linux_sched_setparam_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */
*n_args = 2;
break;
}
- /* sched_getparam */
+ /* linux_sched_getparam */
case 155: {
- struct sched_getparam_args *p = params;
- iarg[0] = p->pid; /* pid_t */
- uarg[1] = (intptr_t) p->param; /* struct sched_param * */
+ struct linux_sched_getparam_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */
*n_args = 2;
break;
}
@@ -1234,7 +1234,11 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_rt_sigqueueinfo */
case 178: {
- *n_args = 0;
+ struct linux_rt_sigqueueinfo_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->sig; /* l_int */
+ uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */
+ *n_args = 3;
break;
}
/* linux_rt_sigsuspend */
@@ -1693,17 +1697,29 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_epoll_create */
case 254: {
- *n_args = 0;
+ struct linux_epoll_create_args *p = params;
+ iarg[0] = p->size; /* l_int */
+ *n_args = 1;
break;
}
/* linux_epoll_ctl */
case 255: {
- *n_args = 0;
+ struct linux_epoll_ctl_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ iarg[1] = p->op; /* l_int */
+ iarg[2] = p->fd; /* l_int */
+ uarg[3] = (intptr_t) p->event; /* struct epoll_event * */
+ *n_args = 4;
break;
}
/* linux_epoll_wait */
case 256: {
- *n_args = 0;
+ struct linux_epoll_wait_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ uarg[1] = (intptr_t) p->events; /* struct epoll_event * */
+ iarg[2] = p->maxevents; /* l_int */
+ iarg[3] = p->timeout; /* l_int */
+ *n_args = 4;
break;
}
/* linux_remap_file_pages */
@@ -1886,7 +1902,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_waitid */
case 284: {
- *n_args = 0;
+ struct linux_waitid_args *p = params;
+ iarg[0] = p->idtype; /* int */
+ iarg[1] = p->id; /* l_pid_t */
+ uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */
+ iarg[3] = p->options; /* int */
+ uarg[4] = (intptr_t) p->rusage; /* struct l_rusage * */
+ *n_args = 5;
break;
}
/* linux_add_key */
@@ -2057,18 +2079,30 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
iarg[0] = p->dfd; /* l_int */
uarg[1] = (intptr_t) p->filename; /* const char * */
iarg[2] = p->amode; /* l_int */
- iarg[3] = p->flag; /* int */
- *n_args = 4;
+ *n_args = 3;
break;
}
/* linux_pselect6 */
case 308: {
- *n_args = 0;
+ struct linux_pselect6_args *p = params;
+ iarg[0] = p->nfds; /* l_int */
+ uarg[1] = (intptr_t) p->readfds; /* l_fd_set * */
+ uarg[2] = (intptr_t) p->writefds; /* l_fd_set * */
+ uarg[3] = (intptr_t) p->exceptfds; /* l_fd_set * */
+ uarg[4] = (intptr_t) p->tsp; /* struct l_timespec * */
+ uarg[5] = (intptr_t) p->sig; /* l_uintptr_t * */
+ *n_args = 6;
break;
}
/* linux_ppoll */
case 309: {
- *n_args = 0;
+ struct linux_ppoll_args *p = params;
+ uarg[0] = (intptr_t) p->fds; /* struct pollfd * */
+ uarg[1] = p->nfds; /* uint32_t */
+ uarg[2] = (intptr_t) p->tsp; /* struct l_timespec * */
+ uarg[3] = (intptr_t) p->sset; /* l_sigset_t * */
+ iarg[4] = p->ssize; /* l_size_t */
+ *n_args = 5;
break;
}
/* linux_unshare */
@@ -2125,12 +2159,23 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_epoll_pwait */
case 319: {
- *n_args = 0;
+ struct linux_epoll_pwait_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ uarg[1] = (intptr_t) p->events; /* struct epoll_event * */
+ iarg[2] = p->maxevents; /* l_int */
+ iarg[3] = p->timeout; /* l_int */
+ uarg[4] = (intptr_t) p->mask; /* l_sigset_t * */
+ *n_args = 5;
break;
}
/* linux_utimensat */
case 320: {
- *n_args = 0;
+ struct linux_utimensat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->pathname; /* const char * */
+ uarg[2] = (intptr_t) p->times; /* const struct l_timespec * */
+ iarg[3] = p->flags; /* l_int */
+ *n_args = 4;
break;
}
/* linux_signalfd */
@@ -2145,12 +2190,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_eventfd */
case 323: {
- *n_args = 0;
+ struct linux_eventfd_args *p = params;
+ iarg[0] = p->initval; /* l_uint */
+ *n_args = 1;
break;
}
/* linux_fallocate */
case 324: {
- *n_args = 0;
+ struct linux_fallocate_args *p = params;
+ iarg[0] = p->fd; /* l_int */
+ iarg[1] = p->mode; /* l_int */
+ iarg[2] = p->offset; /* l_loff_t */
+ iarg[3] = p->len; /* l_loff_t */
+ *n_args = 4;
break;
}
/* linux_timerfd_settime */
@@ -2170,17 +2222,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_eventfd2 */
case 328: {
- *n_args = 0;
+ struct linux_eventfd2_args *p = params;
+ iarg[0] = p->initval; /* l_uint */
+ iarg[1] = p->flags; /* l_int */
+ *n_args = 2;
break;
}
/* linux_epoll_create1 */
case 329: {
- *n_args = 0;
+ struct linux_epoll_create1_args *p = params;
+ iarg[0] = p->flags; /* l_int */
+ *n_args = 1;
break;
}
/* linux_dup3 */
case 330: {
- *n_args = 0;
+ struct linux_dup3_args *p = params;
+ iarg[0] = p->oldfd; /* l_int */
+ iarg[1] = p->newfd; /* l_int */
+ iarg[2] = p->flags; /* l_int */
+ *n_args = 3;
break;
}
/* linux_pipe2 */
@@ -2218,7 +2279,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_recvmmsg */
case 337: {
- *n_args = 0;
+ struct linux_recvmmsg_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */
+ iarg[2] = p->vlen; /* l_uint */
+ iarg[3] = p->flags; /* l_uint */
+ uarg[4] = (intptr_t) p->timeout; /* struct l_timespec * */
+ *n_args = 5;
break;
}
/* linux_fanotify_init */
@@ -2233,7 +2300,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_prlimit64 */
case 340: {
- *n_args = 0;
+ struct linux_prlimit64_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->resource; /* l_uint */
+ uarg[2] = (intptr_t) p->new; /* struct rlimit * */
+ uarg[3] = (intptr_t) p->old; /* struct rlimit * */
+ *n_args = 4;
break;
}
/* linux_name_to_handle_at */
@@ -2253,12 +2325,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_syncfs */
case 344: {
- *n_args = 0;
+ struct linux_syncfs_args *p = params;
+ iarg[0] = p->fd; /* l_int */
+ *n_args = 1;
break;
}
/* linux_sendmmsg */
case 345: {
- *n_args = 0;
+ struct linux_sendmmsg_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */
+ iarg[2] = p->vlen; /* l_uint */
+ iarg[3] = p->flags; /* l_uint */
+ *n_args = 4;
break;
}
/* linux_setns */
@@ -2287,7 +2366,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
const char *p = NULL;
switch (sysnum) {
#define nosys linux_nosys
- /* sys_exit */
+ /* linux_exit */
case 1:
switch(ndx) {
case 0:
@@ -3848,27 +3927,27 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
/* munlockall */
case 153:
break;
- /* sched_setparam */
+ /* linux_sched_setparam */
case 154:
switch(ndx) {
case 0:
- p = "pid_t";
+ p = "l_pid_t";
break;
case 1:
- p = "const struct sched_param *";
+ p = "struct l_sched_param *";
break;
default:
break;
};
break;
- /* sched_getparam */
+ /* linux_sched_getparam */
case 155:
switch(ndx) {
case 0:
- p = "pid_t";
+ p = "l_pid_t";
break;
case 1:
- p = "struct sched_param *";
+ p = "struct l_sched_param *";
break;
default:
break;
@@ -4161,6 +4240,19 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_rt_sigqueueinfo */
case 178:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_siginfo_t *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_rt_sigsuspend */
case 179:
@@ -4823,12 +4915,51 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_epoll_create */
case 254:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_epoll_ctl */
case 255:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "struct epoll_event *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_epoll_wait */
case 256:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct epoll_event *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_remap_file_pages */
case 257:
@@ -5068,6 +5199,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_waitid */
case 284:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "l_pid_t";
+ break;
+ case 2:
+ p = "l_siginfo_t *";
+ break;
+ case 3:
+ p = "int";
+ break;
+ case 4:
+ p = "struct l_rusage *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_add_key */
case 286:
@@ -5327,18 +5477,56 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 2:
p = "l_int";
break;
- case 3:
- p = "int";
- break;
default:
break;
};
break;
/* linux_pselect6 */
case 308:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_fd_set *";
+ break;
+ case 2:
+ p = "l_fd_set *";
+ break;
+ case 3:
+ p = "l_fd_set *";
+ break;
+ case 4:
+ p = "struct l_timespec *";
+ break;
+ case 5:
+ p = "l_uintptr_t *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_ppoll */
case 309:
+ switch(ndx) {
+ case 0:
+ p = "struct pollfd *";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "struct l_timespec *";
+ break;
+ case 3:
+ p = "l_sigset_t *";
+ break;
+ case 4:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_unshare */
case 310:
@@ -5392,9 +5580,44 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_epoll_pwait */
case 319:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct epoll_event *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ case 4:
+ p = "l_sigset_t *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_utimensat */
case 320:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "const struct l_timespec *";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_signalfd */
case 321:
@@ -5404,9 +5627,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_eventfd */
case 323:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
break;
/* linux_fallocate */
case 324:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_loff_t";
+ break;
+ case 3:
+ p = "l_loff_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_timerfd_settime */
case 325:
@@ -5419,12 +5665,42 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_eventfd2 */
case 328:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_epoll_create1 */
case 329:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_dup3 */
case 330:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_pipe2 */
case 331:
@@ -5456,6 +5732,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_recvmmsg */
case 337:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_mmsghdr *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ case 3:
+ p = "l_uint";
+ break;
+ case 4:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_fanotify_init */
case 338:
@@ -5465,6 +5760,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_prlimit64 */
case 340:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_uint";
+ break;
+ case 2:
+ p = "struct rlimit *";
+ break;
+ case 3:
+ p = "struct rlimit *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_name_to_handle_at */
case 341:
@@ -5477,9 +5788,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_syncfs */
case 344:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_sendmmsg */
case 345:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_mmsghdr *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ case 3:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
break;
/* linux_setns */
case 346:
@@ -5502,7 +5836,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
const char *p = NULL;
switch (sysnum) {
#define nosys linux_nosys
- /* sys_exit */
+ /* linux_exit */
case 1:
if (ndx == 0 || ndx == 1)
p = "void";
@@ -6112,12 +6446,12 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* munlockall */
case 153:
- /* sched_setparam */
+ /* linux_sched_setparam */
case 154:
if (ndx == 0 || ndx == 1)
p = "int";
break;
- /* sched_getparam */
+ /* linux_sched_getparam */
case 155:
if (ndx == 0 || ndx == 1)
p = "int";
@@ -6220,6 +6554,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_rt_sigqueueinfo */
case 178:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_rt_sigsuspend */
case 179:
if (ndx == 0 || ndx == 1)
@@ -6469,10 +6806,19 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 253:
/* linux_epoll_create */
case 254:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_epoll_ctl */
case 255:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_epoll_wait */
case 256:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_remap_file_pages */
case 257:
/* linux_set_tid_address */
@@ -6569,6 +6915,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 283:
/* linux_waitid */
case 284:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_add_key */
case 286:
/* linux_request_key */
@@ -6654,8 +7003,14 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_pselect6 */
case 308:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_ppoll */
case 309:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_unshare */
case 310:
/* linux_set_robust_list */
@@ -6682,16 +7037,28 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 318:
/* linux_epoll_pwait */
case 319:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_utimensat */
case 320:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_signalfd */
case 321:
/* linux_timerfd_create */
case 322:
/* linux_eventfd */
case 323:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_fallocate */
case 324:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_timerfd_settime */
case 325:
/* linux_timerfd_gettime */
@@ -6700,10 +7067,19 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 327:
/* linux_eventfd2 */
case 328:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_epoll_create1 */
case 329:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_dup3 */
case 330:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_pipe2 */
case 331:
if (ndx == 0 || ndx == 1)
@@ -6721,12 +7097,18 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 336:
/* linux_recvmmsg */
case 337:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_fanotify_init */
case 338:
/* linux_fanotify_mark */
case 339:
/* linux_prlimit64 */
case 340:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_name_to_handle_at */
case 341:
/* linux_open_by_handle_at */
@@ -6735,8 +7117,14 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 343:
/* linux_syncfs */
case 344:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_sendmmsg */
case 345:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_setns */
case 346:
/* linux_process_vm_readv */
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index c06ce1198f86..4364438c6075 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -83,11 +83,10 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.h>
+#include <compat/linux/linux_vdso.h>
MODULE_VERSION(linux, 1);
-MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
-
#define AUXARGS_ENTRY_32(pos, id, val) \
do { \
suword32(pos++, id); \
@@ -109,15 +108,16 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
#define LINUX_SYS_linux_rt_sendsig 0
#define LINUX_SYS_linux_sendsig 0
-const char *linux_platform = "i686";
-static int linux_szplatform;
-extern char linux_sigcode[];
-extern int linux_szsigcode;
+const char *linux_kplatform;
+static int linux_szsigcode;
+static vm_object_t linux_shared_page_obj;
+static char *linux_shared_page_mapping;
+extern char _binary_linux32_locore_o_start;
+extern char _binary_linux32_locore_o_end;
extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
-SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
static int elf_linux_fixup(register_t **stack_base,
struct image_params *iparams);
@@ -127,9 +127,8 @@ static void exec_linux_setregs(struct thread *td,
struct image_params *imgp, u_long stack);
static void linux32_fixlimit(struct rlimit *rl, int which);
static boolean_t linux32_trans_osrel(const Elf_Note *note, int32_t *osrel);
-
-static eventhandler_tag linux_exit_tag;
-static eventhandler_tag linux_exec_tag;
+static void linux_vdso_install(void *param);
+static void linux_vdso_deinstall(void *param);
/*
* Linux syscalls return negative errno's, we do positive and map them
@@ -151,28 +150,6 @@ static int bsd_to_linux_errno[ELAST + 1] = {
-72, -67, -71
};
-int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
- LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
- LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
- LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS,
- LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
- LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
- LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
- LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
- 0, LINUX_SIGUSR1, LINUX_SIGUSR2
-};
-
-int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
- SIGHUP, SIGINT, SIGQUIT, SIGILL,
- SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
- SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
- SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
- SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
- SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
- SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
- SIGIO, SIGURG, SIGSYS
-};
-
#define LINUX_T_UNKNOWN 255
static int _bsd_to_linux_trapcode[] = {
LINUX_T_UNKNOWN, /* 0 */
@@ -219,6 +196,11 @@ struct linux32_ps_strings {
u_int ps_nenvstr; /* the number of environment strings */
};
+LINUX_VDSO_SYM_INTPTR(linux32_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux32_rt_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux32_vsyscall);
+LINUX_VDSO_SYM_CHAR(linux_platform);
+
/*
* If FreeBSD & Linux have a difference of opinion about what a trap
* means, deal with it here.
@@ -246,11 +228,10 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
{
Elf32_Auxargs *args;
Elf32_Addr *base;
- Elf32_Addr *pos, *uplatform;
+ Elf32_Addr *pos;
struct linux32_ps_strings *arginfo;
arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
- uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform);
KASSERT(curthread->td_proc == imgp->proc,
("unsafe elf_linux_fixup(), should be curproc"));
@@ -258,6 +239,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
args = (Elf32_Auxargs *)imgp->auxargs;
pos = base + (imgp->args->argc + imgp->args->envc + 2);
+ AUXARGS_ENTRY_32(pos, LINUX_AT_SYSINFO_EHDR,
+ imgp->proc->p_sysent->sv_shared_page_base);
+ AUXARGS_ENTRY_32(pos, LINUX_AT_SYSINFO, linux32_vsyscall);
AUXARGS_ENTRY_32(pos, LINUX_AT_HWCAP, cpu_feature);
/*
@@ -282,7 +266,10 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
AUXARGS_ENTRY_32(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
AUXARGS_ENTRY_32(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
AUXARGS_ENTRY_32(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
- AUXARGS_ENTRY_32(pos, LINUX_AT_PLATFORM, PTROUT(uplatform));
+ AUXARGS_ENTRY_32(pos, LINUX_AT_PLATFORM, PTROUT(linux_platform));
+ AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, PTROUT(imgp->canary));
+ if (imgp->execpathp != 0)
+ AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, PTROUT(imgp->execpathp));
if (args->execfd != -1)
AUXARGS_ENTRY_32(pos, AT_EXECFD, args->execfd);
AUXARGS_ENTRY_32(pos, AT_NULL, 0);
@@ -293,11 +280,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
base--;
suword32(base, (uint32_t)imgp->args->argc);
*stack_base = (register_t *)base;
- return 0;
+ return (0);
}
-extern unsigned long linux_sznonrtsigcode;
-
static void
linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
@@ -337,9 +322,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/*
* Build the argument list for the signal handler.
*/
- if (p->p_sysent->sv_sigtbl)
- if (sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
+ sig = bsd_to_linux_signal(sig);
bzero(&frame, sizeof(frame));
@@ -352,7 +335,8 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
ksiginfo_to_lsiginfo(ksi, &frame.sf_si, sig);
/*
- * Build the signal context to be used by sigreturn.
+ * Build the signal context to be used by sigreturn
+ * and libgcc unwind.
*/
frame.sf_sc.uc_flags = 0; /* XXX ??? */
frame.sf_sc.uc_link = 0; /* XXX ??? */
@@ -365,11 +349,12 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
- frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0];
+ frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__mask;
frame.sf_sc.uc_mcontext.sc_edi = regs->tf_rdi;
frame.sf_sc.uc_mcontext.sc_esi = regs->tf_rsi;
frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_rbp;
frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_rbx;
+ frame.sf_sc.uc_mcontext.sc_esp = regs->tf_rsp;
frame.sf_sc.uc_mcontext.sc_edx = regs->tf_rdx;
frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_rcx;
frame.sf_sc.uc_mcontext.sc_eax = regs->tf_rax;
@@ -411,7 +396,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
* Build context to run handler in.
*/
regs->tf_rsp = PTROUT(fp);
- regs->tf_rip = p->p_sysent->sv_sigcode_base + linux_sznonrtsigcode;
+ regs->tf_rip = linux32_rt_sigcode;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
@@ -445,7 +430,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
struct trapframe *regs;
struct l_sigframe *fp, frame;
l_sigset_t lmask;
- int oonstack, i;
+ int oonstack;
int sig, code;
sig = ksi->ksi_signo;
@@ -483,9 +468,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/*
* Build the argument list for the signal handler.
*/
- if (p->p_sysent->sv_sigtbl)
- if (sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
+ sig = bsd_to_linux_signal(sig);
bzero(&frame, sizeof(frame));
@@ -497,7 +480,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/*
* Build the signal context to be used by sigreturn.
*/
- frame.sf_sc.sc_mask = lmask.__bits[0];
+ frame.sf_sc.sc_mask = lmask.__mask;
frame.sf_sc.sc_gs = regs->tf_gs;
frame.sf_sc.sc_fs = regs->tf_fs;
frame.sf_sc.sc_es = regs->tf_es;
@@ -506,6 +489,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
frame.sf_sc.sc_esi = regs->tf_rsi;
frame.sf_sc.sc_ebp = regs->tf_rbp;
frame.sf_sc.sc_ebx = regs->tf_rbx;
+ frame.sf_sc.sc_esp = regs->tf_rsp;
frame.sf_sc.sc_edx = regs->tf_rdx;
frame.sf_sc.sc_ecx = regs->tf_rcx;
frame.sf_sc.sc_eax = regs->tf_rax;
@@ -518,8 +502,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
frame.sf_sc.sc_cr2 = (u_int32_t)(uintptr_t)ksi->ksi_addr;
frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
- for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
- frame.sf_extramask[i] = lmask.__bits[i+1];
+ frame.sf_extramask[0] = lmask.__mask;
if (copyout(&frame, fp, sizeof(frame)) != 0) {
/*
@@ -534,7 +517,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
* Build context to run handler in.
*/
regs->tf_rsp = PTROUT(fp);
- regs->tf_rip = p->p_sysent->sv_sigcode_base;
+ regs->tf_rip = linux32_sigcode;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
@@ -565,7 +548,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
struct trapframe *regs;
sigset_t bmask;
l_sigset_t lmask;
- int eflags, i;
+ int eflags;
ksiginfo_t ksi;
regs = td->td_frame;
@@ -606,9 +589,8 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
return(EINVAL);
}
- lmask.__bits[0] = frame.sf_sc.sc_mask;
- for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
- lmask.__bits[i+1] = frame.sf_extramask[i];
+ lmask.__mask = frame.sf_sc.sc_mask;
+ lmask.__mask = frame.sf_extramask[0];
linux_to_bsd_sigset(&lmask, &bmask);
kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
@@ -758,7 +740,8 @@ linux32_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
sa->code = frame->tf_rax;
if (sa->code >= p->p_sysent->sv_size)
- sa->callp = &p->p_sysent->sv_table[0];
+ /* nosys */
+ sa->callp = &p->p_sysent->sv_table[LINUX_SYS_MAXSYSCALL];
else
sa->callp = &p->p_sysent->sv_table[sa->code];
sa->narg = sa->callp->sy_narg;
@@ -862,21 +845,36 @@ linux_copyout_strings(struct image_params *imgp)
char *stringp, *destp;
u_int32_t *stack_base;
struct linux32_ps_strings *arginfo;
+ char canary[LINUX_AT_RANDOM_LEN];
+ size_t execpath_len;
/*
* Calculate string base and vector table pointers.
- * Also deal with signal trampoline code for this exec type.
*/
+ if (imgp->execpath != NULL && imgp->auxargs != NULL)
+ execpath_len = strlen(imgp->execpath) + 1;
+ else
+ execpath_len = 0;
+
arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
- destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform -
- roundup((ARG_MAX - imgp->args->stringspace),
- sizeof(char *));
+ destp = (caddr_t)arginfo - SPARE_USRSPACE -
+ roundup(sizeof(canary), sizeof(char *)) -
+ roundup(execpath_len, sizeof(char *)) -
+ roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
+
+ if (execpath_len != 0) {
+ imgp->execpathp = (uintptr_t)arginfo - execpath_len;
+ copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len);
+ }
/*
- * Install LINUX_PLATFORM
+ * Prepare the canary for SSP.
*/
- copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform),
- linux_szplatform);
+ arc4rand(canary, sizeof(canary), 0);
+ imgp->canary = (uintptr_t)arginfo -
+ roundup(execpath_len, sizeof(char *)) -
+ roundup(sizeof(canary), sizeof(char *));
+ copyout(canary, (void *)imgp->canary, sizeof(canary));
/*
* If we have a valid auxargs ptr, prepare some room
@@ -970,6 +968,13 @@ static u_long linux32_maxvmem = LINUX32_MAXVMEM;
SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW,
&linux32_maxvmem, 0, "");
+#if defined(DEBUG)
+SYSCTL_PROC(_compat_linux32, OID_AUTO, debug,
+ CTLTYPE_STRING | CTLFLAG_RW,
+ 0, 0, linux_sysctl_debug, "A",
+ "Linux debugging control");
+#endif
+
static void
linux32_fixlimit(struct rlimit *rl, int which)
{
@@ -1006,14 +1011,14 @@ struct sysentvec elf_linux_sysvec = {
.sv_size = LINUX_SYS_MAXSYSCALL,
.sv_table = linux_sysent,
.sv_mask = 0,
- .sv_sigsize = LINUX_SIGTBLSZ,
- .sv_sigtbl = bsd_to_linux_signal,
+ .sv_sigsize = 0,
+ .sv_sigtbl = NULL,
.sv_errsize = ELAST + 1,
.sv_errtbl = bsd_to_linux_errno,
.sv_transtrap = translate_traps,
.sv_fixup = elf_linux_fixup,
.sv_sendsig = linux_sendsig,
- .sv_sigcode = linux_sigcode,
+ .sv_sigcode = &_binary_linux32_locore_o_start,
.sv_szsigcode = &linux_szsigcode,
.sv_prepsyscall = NULL,
.sv_name = "Linux ELF32",
@@ -1037,8 +1042,44 @@ struct sysentvec elf_linux_sysvec = {
.sv_shared_page_base = LINUX32_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
+ .sv_thread_detach = linux_thread_detach,
};
-INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
+
+static void
+linux_vdso_install(void *param)
+{
+
+ linux_szsigcode = (&_binary_linux32_locore_o_end -
+ &_binary_linux32_locore_o_start);
+
+ if (linux_szsigcode > elf_linux_sysvec.sv_shared_page_len)
+ panic("Linux invalid vdso size\n");
+
+ __elfN(linux_vdso_fixup)(&elf_linux_sysvec);
+
+ linux_shared_page_obj = __elfN(linux_shared_page_init)
+ (&linux_shared_page_mapping);
+
+ __elfN(linux_vdso_reloc)(&elf_linux_sysvec, LINUX32_SHAREDPAGE);
+
+ bcopy(elf_linux_sysvec.sv_sigcode, linux_shared_page_mapping,
+ linux_szsigcode);
+ elf_linux_sysvec.sv_shared_page_obj = linux_shared_page_obj;
+
+ linux_kplatform = linux_shared_page_mapping +
+ (linux_platform - (caddr_t)LINUX32_SHAREDPAGE);
+}
+SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_ANY,
+ (sysinit_cfunc_t)linux_vdso_install, NULL);
+
+static void
+linux_vdso_deinstall(void *param)
+{
+
+ __elfN(linux_shared_page_fini)(linux_shared_page_obj);
+};
+SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST,
+ (sysinit_cfunc_t)linux_vdso_deinstall, NULL);
static char GNU_ABI_VENDOR[] = "GNU";
static int GNULINUX_ABI_DESC = 0;
@@ -1110,7 +1151,6 @@ linux_elf_modevent(module_t mod, int type, void *data)
Elf32_Brandinfo **brandinfo;
int error;
struct linux_ioctl_handler **lihp;
- struct linux_device_handler **ldhp;
error = 0;
@@ -1123,19 +1163,8 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (error == 0) {
SET_FOREACH(lihp, linux_ioctl_handler_set)
linux_ioctl_register_handler(*lihp);
- SET_FOREACH(ldhp, linux_device_handler_set)
- linux_device_register_handler(*ldhp);
- mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF);
- sx_init(&emul_shared_lock, "emuldata->shared lock");
LIST_INIT(&futex_list);
mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF);
- linux_exit_tag = EVENTHANDLER_REGISTER(process_exit,
- linux_proc_exit, NULL, 1000);
- linux_exec_tag = EVENTHANDLER_REGISTER(process_exec,
- linux_proc_exec, NULL, 1000);
- linux_szplatform = roundup(strlen(linux_platform) + 1,
- sizeof(char *));
- linux_osd_jail_register();
stclohz = (stathz ? stathz : hz);
if (bootverbose)
printf("Linux ELF exec handler installed\n");
@@ -1156,23 +1185,16 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (error == 0) {
SET_FOREACH(lihp, linux_ioctl_handler_set)
linux_ioctl_unregister_handler(*lihp);
- SET_FOREACH(ldhp, linux_device_handler_set)
- linux_device_unregister_handler(*ldhp);
- mtx_destroy(&emul_lock);
- sx_destroy(&emul_shared_lock);
mtx_destroy(&futex_mtx);
- EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
- EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
- linux_osd_jail_deregister();
if (bootverbose)
printf("Linux ELF exec handler removed\n");
} else
printf("Could not deinstall ELF interpreter entry\n");
break;
default:
- return EOPNOTSUPP;
+ return (EOPNOTSUPP);
}
- return error;
+ return (error);
}
static moduledata_t linux_elf_mod = {
@@ -1182,3 +1204,4 @@ static moduledata_t linux_elf_mod = {
};
DECLARE_MODULE_TIED(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
+MODULE_DEPEND(linuxelf, linux_common, 1, 1, 1);
diff --git a/sys/amd64/linux32/linux32_vdso.lds.s b/sys/amd64/linux32/linux32_vdso.lds.s
new file mode 100644
index 000000000000..a49c209a1ebc
--- /dev/null
+++ b/sys/amd64/linux32/linux32_vdso.lds.s
@@ -0,0 +1,66 @@
+/*
+ * Linker script for 32-bit vDSO.
+ * Copied from Linux kernel arch/x86/vdso/vdso-layout.lds.S
+ * and arch/x86/vdso/vdso32/vdso32.lds.S
+ *
+ * $FreeBSD$
+ */
+
+SECTIONS
+{
+ . = . + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+ .data : {
+ *(.data*)
+ *(.sdata*)
+ *(.got.plt) *(.got)
+ *(.gnu.linkonce.d.*)
+ *(.bss*)
+ *(.dynbss*)
+ *(.gnu.linkonce.b.*)
+ }
+
+ .altinstructions : { *(.altinstructions) }
+ .altinstr_replacement : { *(.altinstr_replacement) }
+
+ . = ALIGN(0x100);
+ .text : { *(.text*) } :text =0x90909090
+}
+
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
+
+ENTRY(linux32_vsyscall);
+
+VERSION
+{
+ LINUX_2.5 {
+ global:
+ linux32_vsyscall;
+ linux32_sigcode;
+ linux32_rt_sigcode;
+ linux_platform;
+ local: *;
+ };
+}
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index 5b39dc39a74f..5f688f3c3b4f 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -38,8 +38,7 @@
; #ifdef's, etc. may be included, and are copied to the output files.
0 AUE_NULL UNIMPL setup
-1 AUE_EXIT NOPROTO { void sys_exit(int rval); } exit \
- sys_exit_args void
+1 AUE_EXIT STD { void linux_exit(int rval); }
2 AUE_FORK STD { int linux_fork(void); }
3 AUE_NULL NOPROTO { int read(int fd, char *buf, \
u_int nbyte); }
@@ -268,10 +267,10 @@
151 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, size_t len); }
152 AUE_MLOCKALL NOPROTO { int mlockall(int how); }
153 AUE_MUNLOCKALL NOPROTO { int munlockall(void); }
-154 AUE_SCHED_SETPARAM NOPROTO { int sched_setparam(pid_t pid, \
- const struct sched_param *param); }
-155 AUE_SCHED_GETPARAM NOPROTO { int sched_getparam(pid_t pid, \
- struct sched_param *param); }
+154 AUE_SCHED_SETPARAM STD { int linux_sched_setparam(l_pid_t pid, \
+ struct l_sched_param *param); }
+155 AUE_SCHED_GETPARAM STD { int linux_sched_getparam(l_pid_t pid, \
+ struct l_sched_param *param); }
156 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( \
l_pid_t pid, l_int policy, \
struct l_sched_param *param); }
@@ -319,7 +318,8 @@
l_siginfo_t *ptr, \
struct l_timeval *timeout, \
l_size_t sigsetsize); }
-178 AUE_NULL STD { int linux_rt_sigqueueinfo(void); }
+178 AUE_NULL STD { int linux_rt_sigqueueinfo(l_pid_t pid, l_int sig, \
+ l_siginfo_t *info); }
179 AUE_NULL STD { int linux_rt_sigsuspend( \
l_sigset_t *newset, \
l_size_t sigsetsize); }
@@ -430,9 +430,11 @@
251 AUE_NULL UNIMPL
252 AUE_EXIT STD { int linux_exit_group(int error_code); }
253 AUE_NULL STD { int linux_lookup_dcookie(void); }
-254 AUE_NULL STD { int linux_epoll_create(void); }
-255 AUE_NULL STD { int linux_epoll_ctl(void); }
-256 AUE_NULL STD { int linux_epoll_wait(void); }
+254 AUE_NULL STD { int linux_epoll_create(l_int size); }
+255 AUE_NULL STD { int linux_epoll_ctl(l_int epfd, l_int op, l_int fd, \
+ struct epoll_event *event); }
+256 AUE_NULL STD { int linux_epoll_wait(l_int epfd, struct epoll_event *events, \
+ l_int maxevents, l_int timeout); }
257 AUE_NULL STD { int linux_remap_file_pages(void); }
258 AUE_NULL STD { int linux_set_tid_address(int *tidptr); }
259 AUE_NULL STD { int linux_timer_create(clockid_t clock_id, \
@@ -467,7 +469,9 @@
281 AUE_NULL STD { int linux_mq_notify(void); }
282 AUE_NULL STD { int linux_mq_getsetattr(void); }
283 AUE_NULL STD { int linux_kexec_load(void); }
-284 AUE_NULL STD { int linux_waitid(void); }
+284 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \
+ l_siginfo_t *info, int options, \
+ struct l_rusage *rusage); }
285 AUE_NULL UNIMPL
; linux 2.6.11:
286 AUE_NULL STD { int linux_add_key(void); }
@@ -505,9 +509,13 @@
char *buf, l_int bufsiz); }
306 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \
l_mode_t mode); }
-307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode, int flag); }
-308 AUE_NULL STD { int linux_pselect6(void); }
-309 AUE_NULL STD { int linux_ppoll(void); }
+307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, \
+ l_int amode); }
+308 AUE_SELECT STD { int linux_pselect6(l_int nfds, l_fd_set *readfds, \
+ l_fd_set *writefds, l_fd_set *exceptfds, \
+ struct l_timespec *tsp, l_uintptr_t *sig); }
+309 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \
+ struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); }
310 AUE_NULL STD { int linux_unshare(void); }
; linux 2.6.17:
311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \
@@ -522,22 +530,26 @@
317 AUE_NULL STD { int linux_move_pages(void); }
; linux 2.6.19:
318 AUE_NULL STD { int linux_getcpu(void); }
-319 AUE_NULL STD { int linux_epoll_pwait(void); }
+319 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \
+ l_int maxevents, l_int timeout, l_sigset_t *mask); }
; linux 2.6.22:
-320 AUE_NULL STD { int linux_utimensat(void); }
+320 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \
+ const struct l_timespec *times, l_int flags); }
321 AUE_NULL STD { int linux_signalfd(void); }
322 AUE_NULL STD { int linux_timerfd_create(void); }
-323 AUE_NULL STD { int linux_eventfd(void); }
+323 AUE_NULL STD { int linux_eventfd(l_uint initval); }
; linux 2.6.23:
-324 AUE_NULL STD { int linux_fallocate(void); }
+324 AUE_NULL STD { int linux_fallocate(l_int fd, l_int mode, \
+ l_loff_t offset, l_loff_t len); }
; linux 2.6.25:
325 AUE_NULL STD { int linux_timerfd_settime(void); }
326 AUE_NULL STD { int linux_timerfd_gettime(void); }
; linux 2.6.27:
327 AUE_NULL STD { int linux_signalfd4(void); }
-328 AUE_NULL STD { int linux_eventfd2(void); }
-329 AUE_NULL STD { int linux_epoll_create1(void); }
-330 AUE_NULL STD { int linux_dup3(void); }
+328 AUE_NULL STD { int linux_eventfd2(l_uint initval, l_int flags); }
+329 AUE_NULL STD { int linux_epoll_create1(l_int flags); }
+330 AUE_NULL STD { int linux_dup3(l_int oldfd, \
+ l_int newfd, l_int flags); }
331 AUE_NULL STD { int linux_pipe2(l_int *pipefds, l_int flags); }
332 AUE_NULL STD { int linux_inotify_init1(void); }
; linux 2.6.30:
@@ -547,17 +559,26 @@
335 AUE_NULL STD { int linux_rt_tsigqueueinfo(void); }
336 AUE_NULL STD { int linux_perf_event_open(void); }
; linux 2.6.33:
-337 AUE_NULL STD { int linux_recvmmsg(void); }
+337 AUE_NULL STD { int linux_recvmmsg(l_int s, \
+ struct l_mmsghdr *msg, l_uint vlen, \
+ l_uint flags, struct l_timespec *timeout); }
338 AUE_NULL STD { int linux_fanotify_init(void); }
339 AUE_NULL STD { int linux_fanotify_mark(void); }
; linux 2.6.36:
-340 AUE_NULL STD { int linux_prlimit64(void); }
+340 AUE_NULL STD { int linux_prlimit64(l_pid_t pid, \
+ l_uint resource, \
+ struct rlimit *new, \
+ struct rlimit *old); }
; later:
341 AUE_NULL STD { int linux_name_to_handle_at(void); }
342 AUE_NULL STD { int linux_open_by_handle_at(void); }
343 AUE_NULL STD { int linux_clock_adjtime(void); }
-344 AUE_NULL STD { int linux_syncfs(void); }
-345 AUE_NULL STD { int linux_sendmmsg(void); }
+344 AUE_SYNC STD { int linux_syncfs(l_int fd); }
+345 AUE_NULL STD { int linux_sendmmsg(l_int s, \
+ struct l_mmsghdr *msg, l_uint vlen, \
+ l_uint flags); }
346 AUE_NULL STD { int linux_setns(void); }
347 AUE_NULL STD { int linux_process_vm_readv(void); }
348 AUE_NULL STD { int linux_process_vm_writev(void); }
+; please, keep this line at the end.
+349 AUE_NULL UNIMPL nosys
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index 20e8f765cb9a..b25d69d4b2eb 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -102,8 +102,8 @@ static MALLOC_DEFINE(M_SVM_VLAPIC, "svm-vlapic", "svm-vlapic");
/* Per-CPU context area. */
extern struct pcpu __pcpu[];
-static uint32_t svm_feature; /* AMD SVM features. */
-SYSCTL_UINT(_hw_vmm_svm, OID_AUTO, features, CTLFLAG_RD, &svm_feature, 0,
+static uint32_t svm_feature = ~0U; /* AMD SVM features. */
+SYSCTL_UINT(_hw_vmm_svm, OID_AUTO, features, CTLFLAG_RDTUN, &svm_feature, 0,
"SVM features advertised by CPUID.8000000AH:EDX");
static int disable_npf_assist;
@@ -112,7 +112,7 @@ SYSCTL_INT(_hw_vmm_svm, OID_AUTO, disable_npf_assist, CTLFLAG_RWTUN,
/* Maximum ASIDs supported by the processor */
static uint32_t nasid;
-SYSCTL_UINT(_hw_vmm_svm, OID_AUTO, num_asids, CTLFLAG_RD, &nasid, 0,
+SYSCTL_UINT(_hw_vmm_svm, OID_AUTO, num_asids, CTLFLAG_RDTUN, &nasid, 0,
"Number of ASIDs supported by this processor");
/* Current ASID generation for each host cpu */
@@ -174,9 +174,14 @@ check_svm_features(void)
/* CPUID Fn8000_000A is for SVM */
do_cpuid(0x8000000A, regs);
- svm_feature = regs[3];
+ svm_feature &= regs[3];
- nasid = regs[1];
+ /*
+ * The number of ASIDs can be configured to be less than what is
+ * supported by the hardware but not more.
+ */
+ if (nasid == 0 || nasid > regs[1])
+ nasid = regs[1];
KASSERT(nasid > 1, ("Insufficient ASIDs for guests: %#x", nasid));
/* bhyve requires the Nested Paging feature */
@@ -1900,7 +1905,7 @@ enable_gintr(void)
*/
static int
svm_vmrun(void *arg, int vcpu, register_t rip, pmap_t pmap,
- void *rend_cookie, void *suspended_cookie)
+ struct vm_eventinfo *evinfo)
{
struct svm_regctx *gctx;
struct svm_softc *svm_sc;
@@ -1975,18 +1980,24 @@ svm_vmrun(void *arg, int vcpu, register_t rip, pmap_t pmap,
*/
disable_gintr();
- if (vcpu_suspended(suspended_cookie)) {
+ if (vcpu_suspended(evinfo)) {
enable_gintr();
vm_exit_suspended(vm, vcpu, state->rip);
break;
}
- if (vcpu_rendezvous_pending(rend_cookie)) {
+ if (vcpu_rendezvous_pending(evinfo)) {
enable_gintr();
vm_exit_rendezvous(vm, vcpu, state->rip);
break;
}
+ if (vcpu_reqidle(evinfo)) {
+ enable_gintr();
+ vm_exit_reqidle(vm, vcpu, state->rip);
+ break;
+ }
+
/* We are asked to give the cpu by scheduler. */
if (vcpu_should_yield(vm, vcpu)) {
enable_gintr();
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 4c3f20d6df17..f590586c44b3 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -856,10 +856,11 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
* VM exit and entry respectively. It is also restored from the
* host VMCS area on a VM exit.
*
- * The TSC MSR is exposed read-only. Writes are disallowed as that
- * will impact the host TSC.
- * XXX Writes would be implemented with a wrmsr trap, and
- * then modifying the TSC offset in the VMCS.
+ * The TSC MSR is exposed read-only. Writes are disallowed as
+ * that will impact the host TSC. If the guest does a write
+ * the "use TSC offsetting" execution control is enabled and the
+ * difference between the host TSC and the guest TSC is written
+ * into the TSC offset in the VMCS.
*/
if (guest_msr_rw(vmx, MSR_GSBASE) ||
guest_msr_rw(vmx, MSR_FSBASE) ||
@@ -1130,6 +1131,22 @@ vmx_clear_nmi_window_exiting(struct vmx *vmx, int vcpu)
VCPU_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting");
}
+int
+vmx_set_tsc_offset(struct vmx *vmx, int vcpu, uint64_t offset)
+{
+ int error;
+
+ if ((vmx->cap[vcpu].proc_ctls & PROCBASED_TSC_OFFSET) == 0) {
+ vmx->cap[vcpu].proc_ctls |= PROCBASED_TSC_OFFSET;
+ vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls);
+ VCPU_CTR0(vmx->vm, vcpu, "Enabling TSC offsetting");
+ }
+
+ error = vmwrite(VMCS_TSC_OFFSET, offset);
+
+ return (error);
+}
+
#define NMI_BLOCKING (VMCS_INTERRUPTIBILITY_NMI_BLOCKING | \
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)
#define HWINTR_BLOCKING (VMCS_INTERRUPTIBILITY_STI_BLOCKING | \
@@ -2554,7 +2571,7 @@ vmx_exit_handle_nmi(struct vmx *vmx, int vcpuid, struct vm_exit *vmexit)
static int
vmx_run(void *arg, int vcpu, register_t rip, pmap_t pmap,
- void *rendezvous_cookie, void *suspend_cookie)
+ struct vm_eventinfo *evinfo)
{
int rc, handled, launched;
struct vmx *vmx;
@@ -2623,18 +2640,24 @@ vmx_run(void *arg, int vcpu, register_t rip, pmap_t pmap,
* vmx_inject_interrupts() can suspend the vcpu due to a
* triple fault.
*/
- if (vcpu_suspended(suspend_cookie)) {
+ if (vcpu_suspended(evinfo)) {
enable_intr();
vm_exit_suspended(vmx->vm, vcpu, rip);
break;
}
- if (vcpu_rendezvous_pending(rendezvous_cookie)) {
+ if (vcpu_rendezvous_pending(evinfo)) {
enable_intr();
vm_exit_rendezvous(vmx->vm, vcpu, rip);
break;
}
+ if (vcpu_reqidle(evinfo)) {
+ enable_intr();
+ vm_exit_reqidle(vmx->vm, vcpu, rip);
+ break;
+ }
+
if (vcpu_should_yield(vm, vcpu)) {
enable_intr();
vm_exit_astpending(vmx->vm, vcpu, rip);
diff --git a/sys/amd64/vmm/intel/vmx.h b/sys/amd64/vmm/intel/vmx.h
index bc488614ff74..57f5b28461f6 100644
--- a/sys/amd64/vmm/intel/vmx.h
+++ b/sys/amd64/vmm/intel/vmx.h
@@ -135,6 +135,8 @@ void vmx_call_isr(uintptr_t entry);
u_long vmx_fix_cr0(u_long cr0);
u_long vmx_fix_cr4(u_long cr4);
+int vmx_set_tsc_offset(struct vmx *vmx, int vcpu, uint64_t offset);
+
extern char vmx_exit_guest[];
#endif
diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c
index 3091f687d2c0..91b2c01b24e2 100644
--- a/sys/amd64/vmm/intel/vmx_msr.c
+++ b/sys/amd64/vmm/intel/vmx_msr.c
@@ -474,6 +474,9 @@ vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu)
else
vm_inject_gp(vmx->vm, vcpuid);
break;
+ case MSR_TSC:
+ error = vmx_set_tsc_offset(vmx, vcpuid, val - rdtsc());
+ break;
default:
error = EINVAL;
break;
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 26712955e41e..2c37a1ac2c69 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -95,6 +95,7 @@ struct vcpu {
struct mtx mtx; /* (o) protects 'state' and 'hostcpu' */
enum vcpu_state state; /* (o) vcpu state */
int hostcpu; /* (o) vcpu's host cpu */
+ int reqidle; /* (i) request vcpu to idle */
struct vlapic *vlapic; /* (i) APIC device model */
enum x2apic_state x2apic_state; /* (i) APIC mode */
uint64_t exitintinfo; /* (i) events pending at VM exit */
@@ -164,8 +165,8 @@ static struct vmm_ops *ops;
#define VMM_RESUME() (ops != NULL ? (*ops->resume)() : 0)
#define VMINIT(vm, pmap) (ops != NULL ? (*ops->vminit)(vm, pmap): NULL)
-#define VMRUN(vmi, vcpu, rip, pmap, rptr, sptr) \
- (ops != NULL ? (*ops->vmrun)(vmi, vcpu, rip, pmap, rptr, sptr) : ENXIO)
+#define VMRUN(vmi, vcpu, rip, pmap, evinfo) \
+ (ops != NULL ? (*ops->vmrun)(vmi, vcpu, rip, pmap, evinfo) : ENXIO)
#define VMCLEANUP(vmi) (ops != NULL ? (*ops->vmcleanup)(vmi) : NULL)
#define VMSPACE_ALLOC(min, max) \
(ops != NULL ? (*ops->vmspace_alloc)(min, max) : NULL)
@@ -221,6 +222,28 @@ TUNABLE_INT("hw.vmm.force_iommu", &vmm_force_iommu);
SYSCTL_INT(_hw_vmm, OID_AUTO, force_iommu, CTLFLAG_RDTUN, &vmm_force_iommu, 0,
"Force use of I/O MMU even if no passthrough devices were found.");
+static void vcpu_notify_event_locked(struct vcpu *vcpu, bool lapic_intr);
+
+#ifdef KTR
+static const char *
+vcpu_state2str(enum vcpu_state state)
+{
+
+ switch (state) {
+ case VCPU_IDLE:
+ return ("idle");
+ case VCPU_FROZEN:
+ return ("frozen");
+ case VCPU_RUNNING:
+ return ("running");
+ case VCPU_SLEEPING:
+ return ("sleeping");
+ default:
+ return ("unknown");
+ }
+}
+#endif
+
static void
vcpu_cleanup(struct vm *vm, int i, bool destroy)
{
@@ -255,6 +278,7 @@ vcpu_init(struct vm *vm, int vcpu_id, bool create)
vcpu->vlapic = VLAPIC_INIT(vm->cookie, vcpu_id);
vm_set_x2apic_state(vm, vcpu_id, X2APIC_DISABLED);
+ vcpu->reqidle = 0;
vcpu->exitintinfo = 0;
vcpu->nmi_pending = 0;
vcpu->extint_pending = 0;
@@ -980,11 +1004,13 @@ save_guest_fpustate(struct vcpu *vcpu)
static VMM_STAT(VCPU_IDLE_TICKS, "number of ticks vcpu was idle");
static int
-vcpu_set_state_locked(struct vcpu *vcpu, enum vcpu_state newstate,
+vcpu_set_state_locked(struct vm *vm, int vcpuid, enum vcpu_state newstate,
bool from_idle)
{
+ struct vcpu *vcpu;
int error;
+ vcpu = &vm->vcpu[vcpuid];
vcpu_assert_locked(vcpu);
/*
@@ -993,8 +1019,13 @@ vcpu_set_state_locked(struct vcpu *vcpu, enum vcpu_state newstate,
* ioctl() operating on a vcpu at any point.
*/
if (from_idle) {
- while (vcpu->state != VCPU_IDLE)
+ while (vcpu->state != VCPU_IDLE) {
+ vcpu->reqidle = 1;
+ vcpu_notify_event_locked(vcpu, false);
+ VCPU_CTR1(vm, vcpuid, "vcpu state change from %s to "
+ "idle requested", vcpu_state2str(vcpu->state));
msleep_spin(&vcpu->state, &vcpu->mtx, "vmstat", hz);
+ }
} else {
KASSERT(vcpu->state != VCPU_IDLE, ("invalid transition from "
"vcpu idle state"));
@@ -1031,6 +1062,9 @@ vcpu_set_state_locked(struct vcpu *vcpu, enum vcpu_state newstate,
if (error)
return (EBUSY);
+ VCPU_CTR2(vm, vcpuid, "vcpu state changed from %s to %s",
+ vcpu_state2str(vcpu->state), vcpu_state2str(newstate));
+
vcpu->state = newstate;
if (newstate == VCPU_RUNNING)
vcpu->hostcpu = curcpu;
@@ -1053,11 +1087,11 @@ vcpu_require_state(struct vm *vm, int vcpuid, enum vcpu_state newstate)
}
static void
-vcpu_require_state_locked(struct vcpu *vcpu, enum vcpu_state newstate)
+vcpu_require_state_locked(struct vm *vm, int vcpuid, enum vcpu_state newstate)
{
int error;
- if ((error = vcpu_set_state_locked(vcpu, newstate, false)) != 0)
+ if ((error = vcpu_set_state_locked(vm, vcpuid, newstate, false)) != 0)
panic("Error %d setting state to %d", error, newstate);
}
@@ -1145,7 +1179,7 @@ vm_handle_hlt(struct vm *vm, int vcpuid, bool intr_disabled, bool *retu)
* vcpu returned from VMRUN() and before it acquired the
* vcpu lock above.
*/
- if (vm->rendezvous_func != NULL || vm->suspend)
+ if (vm->rendezvous_func != NULL || vm->suspend || vcpu->reqidle)
break;
if (vm_nmi_pending(vm, vcpuid))
break;
@@ -1182,13 +1216,13 @@ vm_handle_hlt(struct vm *vm, int vcpuid, bool intr_disabled, bool *retu)
}
t = ticks;
- vcpu_require_state_locked(vcpu, VCPU_SLEEPING);
+ vcpu_require_state_locked(vm, vcpuid, VCPU_SLEEPING);
/*
* XXX msleep_spin() cannot be interrupted by signals so
* wake up periodically to check pending signals.
*/
msleep_spin(vcpu, &vcpu->mtx, wmesg, hz);
- vcpu_require_state_locked(vcpu, VCPU_FROZEN);
+ vcpu_require_state_locked(vm, vcpuid, VCPU_FROZEN);
vmm_stat_incr(vm, vcpuid, VCPU_IDLE_TICKS, ticks - t);
}
@@ -1350,9 +1384,9 @@ vm_handle_suspend(struct vm *vm, int vcpuid, bool *retu)
if (vm->rendezvous_func == NULL) {
VCPU_CTR0(vm, vcpuid, "Sleeping during suspend");
- vcpu_require_state_locked(vcpu, VCPU_SLEEPING);
+ vcpu_require_state_locked(vm, vcpuid, VCPU_SLEEPING);
msleep_spin(vcpu, &vcpu->mtx, "vmsusp", hz);
- vcpu_require_state_locked(vcpu, VCPU_FROZEN);
+ vcpu_require_state_locked(vm, vcpuid, VCPU_FROZEN);
} else {
VCPU_CTR0(vm, vcpuid, "Rendezvous during suspend");
vcpu_unlock(vcpu);
@@ -1375,6 +1409,19 @@ vm_handle_suspend(struct vm *vm, int vcpuid, bool *retu)
return (0);
}
+static int
+vm_handle_reqidle(struct vm *vm, int vcpuid, bool *retu)
+{
+ struct vcpu *vcpu = &vm->vcpu[vcpuid];
+
+ vcpu_lock(vcpu);
+ KASSERT(vcpu->reqidle, ("invalid vcpu reqidle %d", vcpu->reqidle));
+ vcpu->reqidle = 0;
+ vcpu_unlock(vcpu);
+ *retu = true;
+ return (0);
+}
+
int
vm_suspend(struct vm *vm, enum vm_suspend_how how)
{
@@ -1432,6 +1479,18 @@ vm_exit_rendezvous(struct vm *vm, int vcpuid, uint64_t rip)
}
void
+vm_exit_reqidle(struct vm *vm, int vcpuid, uint64_t rip)
+{
+ struct vm_exit *vmexit;
+
+ vmexit = vm_exitinfo(vm, vcpuid);
+ vmexit->rip = rip;
+ vmexit->inst_length = 0;
+ vmexit->exitcode = VM_EXITCODE_REQIDLE;
+ vmm_stat_incr(vm, vcpuid, VMEXIT_REQIDLE, 1);
+}
+
+void
vm_exit_astpending(struct vm *vm, int vcpuid, uint64_t rip)
{
struct vm_exit *vmexit;
@@ -1446,6 +1505,7 @@ vm_exit_astpending(struct vm *vm, int vcpuid, uint64_t rip)
int
vm_run(struct vm *vm, struct vm_run *vmrun)
{
+ struct vm_eventinfo evinfo;
int error, vcpuid;
struct vcpu *vcpu;
struct pcb *pcb;
@@ -1453,7 +1513,6 @@ vm_run(struct vm *vm, struct vm_run *vmrun)
struct vm_exit *vme;
bool retu, intr_disabled;
pmap_t pmap;
- void *rptr, *sptr;
vcpuid = vmrun->cpuid;
@@ -1466,11 +1525,12 @@ vm_run(struct vm *vm, struct vm_run *vmrun)
if (CPU_ISSET(vcpuid, &vm->suspended_cpus))
return (EINVAL);
- rptr = &vm->rendezvous_func;
- sptr = &vm->suspend;
pmap = vmspace_pmap(vm->vmspace);
vcpu = &vm->vcpu[vcpuid];
vme = &vcpu->exitinfo;
+ evinfo.rptr = &vm->rendezvous_func;
+ evinfo.sptr = &vm->suspend;
+ evinfo.iptr = &vcpu->reqidle;
restart:
critical_enter();
@@ -1485,7 +1545,7 @@ restart:
restore_guest_fpustate(vcpu);
vcpu_require_state(vm, vcpuid, VCPU_RUNNING);
- error = VMRUN(vm->cookie, vcpuid, vcpu->nextrip, pmap, rptr, sptr);
+ error = VMRUN(vm->cookie, vcpuid, vcpu->nextrip, pmap, &evinfo);
vcpu_require_state(vm, vcpuid, VCPU_FROZEN);
save_guest_fpustate(vcpu);
@@ -1498,6 +1558,9 @@ restart:
retu = false;
vcpu->nextrip = vme->rip + vme->inst_length;
switch (vme->exitcode) {
+ case VM_EXITCODE_REQIDLE:
+ error = vm_handle_reqidle(vm, vcpuid, &retu);
+ break;
case VM_EXITCODE_SUSPENDED:
error = vm_handle_suspend(vm, vcpuid, &retu);
break;
@@ -1536,6 +1599,8 @@ restart:
if (error == 0 && retu == false)
goto restart;
+ VCPU_CTR2(vm, vcpuid, "retu %d/%d", error, vme->exitcode);
+
/* copy the exit information */
bcopy(vme, &vmrun->vm_exit, sizeof(struct vm_exit));
return (error);
@@ -2072,7 +2137,7 @@ vcpu_set_state(struct vm *vm, int vcpuid, enum vcpu_state newstate,
vcpu = &vm->vcpu[vcpuid];
vcpu_lock(vcpu);
- error = vcpu_set_state_locked(vcpu, newstate, from_idle);
+ error = vcpu_set_state_locked(vm, vcpuid, newstate, from_idle);
vcpu_unlock(vcpu);
return (error);
@@ -2168,15 +2233,11 @@ vm_set_x2apic_state(struct vm *vm, int vcpuid, enum x2apic_state state)
* - If the vcpu is running on a different host_cpu then an IPI will be directed
* to the host_cpu to cause the vcpu to trap into the hypervisor.
*/
-void
-vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr)
+static void
+vcpu_notify_event_locked(struct vcpu *vcpu, bool lapic_intr)
{
int hostcpu;
- struct vcpu *vcpu;
-
- vcpu = &vm->vcpu[vcpuid];
- vcpu_lock(vcpu);
hostcpu = vcpu->hostcpu;
if (vcpu->state == VCPU_RUNNING) {
KASSERT(hostcpu != NOCPU, ("vcpu running on invalid hostcpu"));
@@ -2201,6 +2262,15 @@ vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr)
if (vcpu->state == VCPU_SLEEPING)
wakeup_one(vcpu);
}
+}
+
+void
+vcpu_notify_event(struct vm *vm, int vcpuid, bool lapic_intr)
+{
+ struct vcpu *vcpu = &vm->vcpu[vcpuid];
+
+ vcpu_lock(vcpu);
+ vcpu_notify_event_locked(vcpu, lapic_intr);
vcpu_unlock(vcpu);
}
diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c
index 9b5713d5dbb3..758b7e80f77c 100644
--- a/sys/amd64/vmm/vmm_instruction_emul.c
+++ b/sys/amd64/vmm/vmm_instruction_emul.c
@@ -2342,7 +2342,7 @@ verify_gla(struct vm *vm, int cpuid, uint64_t gla, struct vie *vie)
* instruction
*/
if (vie->base_register == VM_REG_GUEST_RIP)
- base += vie->num_valid;
+ base += vie->num_processed;
}
idx = 0;
diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c
index 4ae5fb9132cc..7e2f64d1fe1f 100644
--- a/sys/amd64/vmm/vmm_stat.c
+++ b/sys/amd64/vmm/vmm_stat.c
@@ -164,6 +164,7 @@ VMM_STAT(VMEXIT_NESTED_FAULT, "vm exits due to nested page fault");
VMM_STAT(VMEXIT_INST_EMUL, "vm exits for instruction emulation");
VMM_STAT(VMEXIT_UNKNOWN, "number of vm exits for unknown reason");
VMM_STAT(VMEXIT_ASTPENDING, "number of times astpending at exit");
+VMM_STAT(VMEXIT_REQIDLE, "number of times idle requested at exit");
VMM_STAT(VMEXIT_USERSPACE, "number of vm exits handled in userspace");
VMM_STAT(VMEXIT_RENDEZVOUS, "number of times rendezvous pending at exit");
VMM_STAT(VMEXIT_EXCEPTION, "number of vm exits due to exceptions");
diff --git a/sys/amd64/vmm/vmm_stat.h b/sys/amd64/vmm/vmm_stat.h
index 1640ba37e025..c69584090264 100644
--- a/sys/amd64/vmm/vmm_stat.h
+++ b/sys/amd64/vmm/vmm_stat.h
@@ -157,4 +157,5 @@ VMM_STAT_DECLARE(VMEXIT_ASTPENDING);
VMM_STAT_DECLARE(VMEXIT_USERSPACE);
VMM_STAT_DECLARE(VMEXIT_RENDEZVOUS);
VMM_STAT_DECLARE(VMEXIT_EXCEPTION);
+VMM_STAT_DECLARE(VMEXIT_REQIDLE);
#endif
diff --git a/sys/arm/arm/bcopyinout.S b/sys/arm/arm/bcopyinout.S
index 3624f9268c88..c030e243ec20 100644
--- a/sys/arm/arm/bcopyinout.S
+++ b/sys/arm/arm/bcopyinout.S
@@ -38,6 +38,7 @@
#include "assym.s"
+#include <machine/acle-compat.h>
#include <machine/asm.h>
#include <sys/errno.h>
@@ -54,7 +55,7 @@ __FBSDID("$FreeBSD$");
.text
.align 2
-#ifdef _ARM_ARCH_6
+#if __ARM_ARCH >= 6
#define GET_PCB(tmp) \
mrc p15, 0, tmp, c13, c0, 4; \
add tmp, tmp, #(TD_PCB)
@@ -69,7 +70,7 @@ __FBSDID("$FreeBSD$");
#define SAVE_REGS stmfd sp!, {r4-r11}
#define RESTORE_REGS ldmfd sp!, {r4-r11}
-
+
#if defined(_ARM_ARCH_5E)
#define HELLOCPP #
#define PREFETCH(rx,o) pld [ rx , HELLOCPP (o) ]
@@ -88,7 +89,7 @@ __FBSDID("$FreeBSD$");
* r4-r11 are scratch
*/
ENTRY(copyin)
- /* Quick exit if length is zero */
+ /* Quick exit if length is zero */
teq r2, #0
moveq r0, #0
RETeq
@@ -326,7 +327,7 @@ END(copyin)
*/
ENTRY(copyout)
- /* Quick exit if length is zero */
+ /* Quick exit if length is zero */
teq r2, #0
moveq r0, #0
RETeq
diff --git a/sys/arm/arm/bcopyinout_xscale.S b/sys/arm/arm/bcopyinout_xscale.S
index 487737e65943..7a5abb588d63 100644
--- a/sys/arm/arm/bcopyinout_xscale.S
+++ b/sys/arm/arm/bcopyinout_xscale.S
@@ -38,11 +38,13 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
+#include <machine/acle-compat.h>
+
.syntax unified
.text
.align 2
-#ifdef _ARM_ARCH_6
+#if __ARM_ARCH >= 6
#define GET_PCB(tmp) \
mrc p15, 0, tmp, c13, c0, 4; \
add tmp, tmp, #(TD_PCB)
@@ -85,7 +87,7 @@ ENTRY(copyin)
ldmfd sp!, {r0-r2, r4, lr}
moveq r0, #0
RETeq
-
+
.Lnormal:
stmfd sp!, {r10-r11, lr}
@@ -527,8 +529,8 @@ ENTRY(copyout)
ldmfd sp!, {r0-r2, r4, lr}
moveq r0, #0
RETeq
-
-.Lnormale:
+
+.Lnormale:
stmfd sp!, {r10-r11, lr}
GET_PCB(r10)
@@ -584,7 +586,7 @@ ENTRY(copyout)
ldrne ip, [r0], #0x04
subne r2, r2, #0x04
strtne ip, [r1], #0x04
-
+
stmfd sp!, {r4-r9} /* Free up some registers */
mov r3, #-1 /* Signal restore r4-r9 */
diff --git a/sys/arm/arm/blockio.S b/sys/arm/arm/blockio.S
index 28f502b6d678..eb049c1d6cf2 100644
--- a/sys/arm/arm/blockio.S
+++ b/sys/arm/arm/blockio.S
@@ -43,7 +43,7 @@
*
* Created : 08/10/94
* Modified : 22/01/99 -- R.Earnshaw
- * Faster, and small tweaks for StrongARM
+ * Faster, and small tweaks for StrongARM
*/
#include <machine/asm.h>
@@ -251,7 +251,7 @@ ENTRY(outsw)
str r3, [r0]
str ip, [r0]
-
+
/* mov ip, r3, lsl #16
* orr ip, ip, ip, lsr #16
* str ip, [r0]
@@ -358,7 +358,7 @@ ENTRY(outsw16)
eor r3, r3, r4, lsl #16 /* r3 = (A^B^A)(B) = (B)(B) */
str r3, [r0]
str r4, [r0]
-
+
/* mov r3, r4, lsl #16
* orr r3, r3, r3, lsr #16
* str r3, [r0]
diff --git a/sys/arm/arm/bus_space_base.c b/sys/arm/arm/bus_space_base.c
index 4e4f33ce35ab..0eeaaa399880 100644
--- a/sys/arm/arm/bus_space_base.c
+++ b/sys/arm/arm/bus_space_base.c
@@ -116,10 +116,10 @@ static struct bus_space arm_base_bus_space __aligned(CACHE_LINE_SIZE) = {
.bs_c_8 = BS_UNIMPLEMENTED,
/* read stream (single) */
- .bs_r_1_s = NULL, /* Use inline code in bus.h */
- .bs_r_2_s = NULL, /* Use inline code in bus.h */
- .bs_r_4_s = NULL, /* Use inline code in bus.h */
- .bs_r_8_s = NULL, /* Use inline code in bus.h */
+ .bs_r_1_s = NULL, /* Use inline code in bus.h */
+ .bs_r_2_s = NULL, /* Use inline code in bus.h */
+ .bs_r_4_s = NULL, /* Use inline code in bus.h */
+ .bs_r_8_s = NULL, /* Use inline code in bus.h */
/* read multiple stream */
.bs_rm_1_s = generic_bs_rm_1,
@@ -134,10 +134,10 @@ static struct bus_space arm_base_bus_space __aligned(CACHE_LINE_SIZE) = {
.bs_rr_8_s = BS_UNIMPLEMENTED,
/* write stream (single) */
- .bs_w_1_s = NULL, /* Use inline code in bus.h */
- .bs_w_2_s = NULL, /* Use inline code in bus.h */
- .bs_w_4_s = NULL, /* Use inline code in bus.h */
- .bs_w_8_s = NULL, /* Use inline code in bus.h */
+ .bs_w_1_s = NULL, /* Use inline code in bus.h */
+ .bs_w_2_s = NULL, /* Use inline code in bus.h */
+ .bs_w_4_s = NULL, /* Use inline code in bus.h */
+ .bs_w_8_s = NULL, /* Use inline code in bus.h */
/* write multiple stream */
.bs_wm_1_s = generic_bs_wm_1,
diff --git a/sys/arm/arm/busdma_machdep-v6.c b/sys/arm/arm/busdma_machdep-v6.c
index 7236c5a54c1f..67e053bf1b58 100644
--- a/sys/arm/arm/busdma_machdep-v6.c
+++ b/sys/arm/arm/busdma_machdep-v6.c
@@ -160,7 +160,7 @@ SYSCTL_UINT(_hw_busdma, OID_AUTO, maps_dmamem, CTLFLAG_RD, &maps_dmamem, 0,
"Number of active maps for bus_dmamem_alloc buffers");
SYSCTL_UINT(_hw_busdma, OID_AUTO, maps_coherent, CTLFLAG_RD, &maps_coherent, 0,
"Number of active maps with BUS_DMA_COHERENT flag set");
-SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_total, CTLFLAG_RD,
+SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_total, CTLFLAG_RD,
&maploads_total, "Number of load operations performed");
SYSCTL_COUNTER_U64(_hw_busdma, OID_AUTO, maploads_bounced, CTLFLAG_RD,
&maploads_bounced, "Number of load operations that used bounce buffers");
@@ -230,14 +230,14 @@ busdma_init(void *dummy)
uma_flags = 0;
/* Create a cache of buffers in standard (cacheable) memory. */
- standard_allocator = busdma_bufalloc_create("buffer",
+ standard_allocator = busdma_bufalloc_create("buffer",
arm_dcache_align, /* minimum_alignment */
- NULL, /* uma_alloc func */
+ NULL, /* uma_alloc func */
NULL, /* uma_free func */
uma_flags); /* uma_zcreate_flags */
#ifdef INVARIANTS
- /*
+ /*
* Force UMA zone to allocate service structures like
* slabs using own allocator. uma_debug code performs
* atomic ops on uma_slab_t fields and safety of this
@@ -251,8 +251,8 @@ busdma_init(void *dummy)
*/
coherent_allocator = busdma_bufalloc_create("coherent",
arm_dcache_align, /* minimum_alignment */
- busdma_bufalloc_alloc_uncacheable,
- busdma_bufalloc_free_uncacheable,
+ busdma_bufalloc_alloc_uncacheable,
+ busdma_bufalloc_free_uncacheable,
uma_flags); /* uma_zcreate_flags */
}
@@ -343,7 +343,7 @@ cacheline_bounce(bus_dmamap_t map, bus_addr_t addr, bus_size_t size)
* address spaces.
*/
static __inline int
-might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr,
+might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr,
bus_size_t size)
{
@@ -364,7 +364,7 @@ might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr,
* the DMA needs to bounce, otherwise any DMA within the zone bounces.
*/
static int
-must_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t paddr,
+must_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t paddr,
bus_size_t size)
{
@@ -387,11 +387,11 @@ must_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t paddr,
*/
while (dmat != NULL && exclusion_bounce(dmat)) {
if ((paddr >= dmat->lowaddr && paddr <= dmat->highaddr) &&
- (dmat->filter == NULL ||
+ (dmat->filter == NULL ||
dmat->filter(dmat->filterarg, paddr) != 0))
return (1);
dmat = dmat->parent;
- }
+ }
return (0);
}
@@ -554,7 +554,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
* number of pages in a transfer.
*/
maxsize = roundup2(maxsize, PAGE_SIZE) + PAGE_SIZE;
-
+
if ((error = alloc_bounce_zone(newtag)) != 0) {
free(newtag, M_DEVBUF);
return (error);
@@ -630,7 +630,7 @@ static int allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp)
struct bounce_zone *bz;
int maxpages;
int error;
-
+
if (dmat->bounce_zone == NULL)
if ((error = alloc_bounce_zone(dmat)) != 0)
return (error);
@@ -651,13 +651,13 @@ static int allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp)
if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0 ||
(bz->map_count > 0 && bz->total_bpages < maxpages)) {
int pages;
-
+
pages = atop(roundup2(dmat->maxsize, PAGE_SIZE)) + 1;
pages = MIN(maxpages - bz->total_bpages, pages);
pages = MAX(pages, 2);
if (alloc_bounce_pages(dmat, pages) < pages)
return (ENOMEM);
-
+
if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0)
dmat->flags |= BUS_DMA_MIN_ALLOC_COMP;
}
@@ -676,7 +676,7 @@ allocate_map(bus_dma_tag_t dmat, int mflags)
* variable-sized array of sync_list structures. Following that
* we allocate enough extra space to hold the array of bus_dma_segments.
*/
- KASSERT(dmat->nsegments <= MAX_DMA_SEGMENTS,
+ KASSERT(dmat->nsegments <= MAX_DMA_SEGMENTS,
("cannot allocate %u dma segments (max is %u)",
dmat->nsegments, MAX_DMA_SEGMENTS));
segsize = sizeof(struct bus_dma_segment) * dmat->nsegments;
@@ -931,7 +931,7 @@ _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
else
paddr = pmap_extract(map->pmap, vaddr);
if (must_bounce(dmat, map, paddr,
- min(vendaddr - vaddr, (PAGE_SIZE - ((vm_offset_t)vaddr &
+ min(vendaddr - vaddr, (PAGE_SIZE - ((vm_offset_t)vaddr &
PAGE_MASK)))) != 0) {
map->pagesneeded++;
}
@@ -1267,7 +1267,7 @@ _bus_dmamap_fix_user(vm_offset_t buf, bus_size_t len,
bus_addr_t curaddr;
vm_offset_t va;
- /*
+ /*
* each synclist entry is contained within a single page.
* this would be needed if BUS_DMASYNC_POSTxxxx was implemented
*/
@@ -1339,7 +1339,7 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
cpu_dcache_wb_range((vm_offset_t)bpage->vaddr,
bpage->datacount);
l2cache_wb_range((vm_offset_t)bpage->vaddr,
- (vm_offset_t)bpage->busaddr,
+ (vm_offset_t)bpage->busaddr,
bpage->datacount);
bpage = STAILQ_NEXT(bpage, links);
}
@@ -1387,10 +1387,10 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
startv = bpage->vaddr &~ arm_dcache_align_mask;
startp = bpage->busaddr &~ arm_dcache_align_mask;
len = bpage->datacount;
-
+
if (startv != bpage->vaddr)
len += bpage->vaddr & arm_dcache_align_mask;
- if (len & arm_dcache_align_mask)
+ if (len & arm_dcache_align_mask)
len = (len -
(len & arm_dcache_align_mask)) +
arm_dcache_align;
@@ -1473,7 +1473,7 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
sl->busaddr, 1);
}
cpu_dcache_inv_range(sl->vaddr, sl->datacount);
- l2cache_inv_range(sl->vaddr, sl->busaddr,
+ l2cache_inv_range(sl->vaddr, sl->busaddr,
sl->datacount);
sl++;
}
@@ -1485,7 +1485,7 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
case BUS_DMASYNC_POSTREAD:
case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE:
while (sl != end) {
- l2cache_inv_range(sl->vaddr, sl->busaddr,
+ l2cache_inv_range(sl->vaddr, sl->busaddr,
sl->datacount);
cpu_dcache_inv_range(sl->vaddr, sl->datacount);
sl++;
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index acd8f81ec128..d7498c5d111a 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -237,7 +237,7 @@ dmamap_ctor(void *mem, int size, void *arg, int flags)
* This is the dtor function passed to uma_zcreate() for the pool of dma maps.
* It may need platform-specific changes if this code is copied .
*/
-static void
+static void
dmamap_dtor(void *mem, int size, void *arg)
{
bus_dmamap_t map;
@@ -256,9 +256,9 @@ busdma_init(void *dummy)
dmamap_ctor, dmamap_dtor, NULL, NULL, UMA_ALIGN_PTR, 0);
/* Create a cache of buffers in standard (cacheable) memory. */
- standard_allocator = busdma_bufalloc_create("buffer",
+ standard_allocator = busdma_bufalloc_create("buffer",
arm_dcache_align, /* minimum_alignment */
- NULL, /* uma_alloc func */
+ NULL, /* uma_alloc func */
NULL, /* uma_free func */
0); /* uma_zcreate_flags */
@@ -268,8 +268,8 @@ busdma_init(void *dummy)
*/
coherent_allocator = busdma_bufalloc_create("coherent",
arm_dcache_align, /* minimum_alignment */
- busdma_bufalloc_alloc_uncacheable,
- busdma_bufalloc_free_uncacheable,
+ busdma_bufalloc_alloc_uncacheable,
+ busdma_bufalloc_free_uncacheable,
0); /* uma_zcreate_flags */
}
@@ -308,7 +308,7 @@ run_filter(bus_dma_tag_t dmat, bus_addr_t paddr)
|| (*dmat->filter)(dmat->filterarg, paddr) != 0))
retval = 1;
- dmat = dmat->parent;
+ dmat = dmat->parent;
} while (retval == 0 && dmat != NULL);
return (retval);
}
@@ -531,13 +531,13 @@ bus_dma_tag_destroy(bus_dma_tag_t dmat)
#endif
if (dmat != NULL) {
-
+
if (dmat->map_count != 0)
return (EBUSY);
-
+
while (dmat != NULL) {
bus_dma_tag_t parent;
-
+
parent = dmat->parent;
atomic_subtract_int(&dmat->ref_count, 1);
if (dmat->ref_count == 0) {
@@ -588,7 +588,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp)
* now, because we can't sleep for resources at map load time.
*/
if (dmat->segments == NULL) {
- dmat->segments = malloc(dmat->nsegments *
+ dmat->segments = malloc(dmat->nsegments *
sizeof(*dmat->segments), M_DEVBUF, M_NOWAIT);
if (dmat->segments == NULL) {
free(slist, M_DEVBUF);
@@ -701,7 +701,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddrp, int flags,
* now, because we can't sleep for resources at map load time.
*/
if (dmat->segments == NULL)
- dmat->segments = malloc(dmat->nsegments *
+ dmat->segments = malloc(dmat->nsegments *
sizeof(*dmat->segments), M_DEVBUF, mflags);
slist = malloc(sizeof(*slist) * dmat->nsegments, M_DEVBUF, M_NOWAIT);
@@ -918,7 +918,7 @@ _bus_dmamap_addseg(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t curaddr,
* memory address to an address in the DMA window.
*/
curaddr = (curaddr - dr->dr_sysbase) + dr->dr_busbase;
-
+
}
seg = *segp;
@@ -1206,7 +1206,7 @@ _bus_dmamap_sync_bp(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
STAILQ_FOREACH(bpage, &map->bpages, links) {
if (op & BUS_DMASYNC_PREWRITE) {
if (bpage->datavaddr != 0)
- bcopy((void *)bpage->datavaddr,
+ bcopy((void *)bpage->datavaddr,
(void *)bpage->vaddr, bpage->datacount);
else
physcopyout(bpage->dataaddr,
diff --git a/sys/arm/arm/copystr.S b/sys/arm/arm/copystr.S
index 57c9e700c3df..48c296b09292 100644
--- a/sys/arm/arm/copystr.S
+++ b/sys/arm/arm/copystr.S
@@ -38,8 +38,8 @@
* Created : 16/05/95
*/
-
#include "assym.s"
+#include <machine/acle-compat.h>
#include <machine/asm.h>
#include <machine/armreg.h>
__FBSDID("$FreeBSD$");
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
.text
.align 2
-#ifdef _ARM_ARCH_6
+#if __ARM_ARCH >= 6
#define GET_PCB(tmp) \
mrc p15, 0, tmp, c13, c0, 4; \
add tmp, tmp, #(TD_PCB)
@@ -195,6 +195,7 @@ END(copyoutstr)
/* A fault occurred during the copy */
.Lcopystrfault:
+ mov r0, #EFAULT
mov r1, #0x00000000
str r1, [r4, #PCB_ONFAULT]
RESTORE_REGS
diff --git a/sys/arm/arm/cpu_asm-v6.S b/sys/arm/arm/cpu_asm-v6.S
index b36c9d1f535b..e3dce4cd6377 100644
--- a/sys/arm/arm/cpu_asm-v6.S
+++ b/sys/arm/arm/cpu_asm-v6.S
@@ -26,6 +26,7 @@
*
* $FreeBSD$
*/
+#include "assym.s"
#include <machine/acle-compat.h>
#include <machine/asm.h>
@@ -33,10 +34,21 @@
#include <machine/armreg.h>
#include <machine/sysreg.h>
-/*
+#if __ARM_ARCH >= 6
+#define GET_PCB(tmp) \
+ mrc CP15_TPIDRPRW(tmp); \
+ add tmp, tmp, #(TD_PCB)
+#else
+.Lcurpcb:
+ .word _C_LABEL(__pcpu) + PC_CURPCB
+#define GET_PCB(tmp) \
+ ldr tmp, .Lcurpcb
+#endif
+
+/*
* Define cache functions used by startup code, which counts on the fact that
* only r0-r3,r12 (ip) are modified and no stack space is used. These functions
- * must be called with interrupts disabled. Moreover, these work only with
+ * must be called with interrupts disabled. Moreover, these work only with
* caches integrated to CPU (accessible via CP15); systems with an external L2
* cache controller such as a PL310 need separate calls to that device driver
* to affect L2 caches. This is not a factor during early kernel startup, as
@@ -208,3 +220,59 @@ ASENTRY_NP(dcache_wbinv_poc_all)
bx lr
#endif /* __ARM_ARCH == 6 */
END(dcache_wbinv_poc_all)
+
+ASENTRY_NP(dcache_wb_pou_checked)
+ ldr ip, .Lcpuinfo
+ ldr ip, [ip, #DCACHE_LINE_SIZE]
+
+ GET_PCB(r2)
+ ldr r2, [r2]
+
+ adr r3, _C_LABEL(cachebailout)
+ str r3, [r2, #PCB_ONFAULT]
+1:
+ mcr CP15_DCCMVAC(r0)
+ add r0, r0, ip
+ subs r1, r1, ip
+ bhi 1b
+ DSB
+ mov r0, #0
+ str r0, [r2, #PCB_ONFAULT]
+ mov r0, #1 /* cannot be faulting address */
+ RET
+
+.Lcpuinfo:
+ .word cpuinfo
+END(dcache_wb_pou_checked)
+
+ASENTRY_NP(icache_inv_pou_checked)
+ ldr ip, .Lcpuinfo
+ ldr ip, [ip, #ICACHE_LINE_SIZE]
+
+ GET_PCB(r2)
+ ldr r2, [r2]
+
+ adr r3, _C_LABEL(cachebailout)
+ str r3, [r2, #PCB_ONFAULT]
+
+1:
+ mcr CP15_ICIMVAU(r0)
+ add r0, r0, ip
+ subs r1, r1, ip
+ bhi 1b
+ DSB
+ ISB
+ mov r0, #0
+ str r0, [r2, #PCB_ONFAULT]
+ mov r0, #1 /* cannot be faulting address */
+ RET
+END(icache_inv_pou_checked)
+
+/* label must be global as trap-v6.c references it */
+ .global _C_LABEL(cachebailout)
+_C_LABEL(cachebailout):
+ DSB
+ ISB
+ mov r1, #0
+ str r1, [r2, #PCB_ONFAULT]
+ RET
diff --git a/sys/arm/arm/cpufunc.c b/sys/arm/arm/cpufunc.c
index f3d9a525f419..0b589ed2a1a1 100644
--- a/sys/arm/arm/cpufunc.c
+++ b/sys/arm/arm/cpufunc.c
@@ -361,7 +361,7 @@ struct cpu_functions pj4bv7_cpufuncs = {
struct cpu_functions xscale_cpufuncs = {
/* CPU functions */
-
+
cpufunc_id, /* id */
xscale_cpwait, /* cpwait */
@@ -426,7 +426,7 @@ struct cpu_functions xscale_cpufuncs = {
#ifdef CPU_XSCALE_81342
struct cpu_functions xscalec3_cpufuncs = {
/* CPU functions */
-
+
cpufunc_id, /* id */
xscale_cpwait, /* cpwait */
@@ -553,63 +553,63 @@ struct cpu_functions fa526_cpufuncs = {
#if defined(CPU_ARM1176)
struct cpu_functions arm1176_cpufuncs = {
/* CPU functions */
-
+
cpufunc_id, /* id */
cpufunc_nullop, /* cpwait */
-
+
/* MMU functions */
-
+
cpufunc_control, /* control */
cpufunc_domains, /* Domain */
arm11x6_setttb, /* Setttb */
cpufunc_faultstatus, /* Faultstatus */
cpufunc_faultaddress, /* Faultaddress */
-
+
/* TLB functions */
-
+
arm11_tlb_flushID, /* tlb_flushID */
arm11_tlb_flushID_SE, /* tlb_flushID_SE */
arm11_tlb_flushI, /* tlb_flushI */
arm11_tlb_flushI_SE, /* tlb_flushI_SE */
arm11_tlb_flushD, /* tlb_flushD */
arm11_tlb_flushD_SE, /* tlb_flushD_SE */
-
+
/* Cache operations */
-
+
arm11x6_icache_sync_all, /* icache_sync_all */
arm11x6_icache_sync_range, /* icache_sync_range */
-
+
arm11x6_dcache_wbinv_all, /* dcache_wbinv_all */
armv6_dcache_wbinv_range, /* dcache_wbinv_range */
armv6_dcache_inv_range, /* dcache_inv_range */
armv6_dcache_wb_range, /* dcache_wb_range */
-
+
armv6_idcache_inv_all, /* idcache_inv_all */
arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */
arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */
-
+
(void *)cpufunc_nullop, /* l2cache_wbinv_all */
(void *)cpufunc_nullop, /* l2cache_wbinv_range */
(void *)cpufunc_nullop, /* l2cache_inv_range */
(void *)cpufunc_nullop, /* l2cache_wb_range */
(void *)cpufunc_nullop, /* l2cache_drain_writebuf */
-
+
/* Other functions */
-
+
arm11x6_flush_prefetchbuf, /* flush_prefetchbuf */
arm11_drain_writebuf, /* drain_writebuf */
cpufunc_nullop, /* flush_brnchtgt_C */
(void *)cpufunc_nullop, /* flush_brnchtgt_E */
-
+
arm11x6_sleep, /* sleep */
-
+
/* Soft functions */
-
+
cpufunc_null_fixup, /* dataabt_fixup */
cpufunc_null_fixup, /* prefetchabt_fixup */
-
+
arm11_context_switch, /* context_switch */
-
+
arm11x6_setup /* cpu setup */
};
#endif /*CPU_ARM1176 */
@@ -617,46 +617,46 @@ struct cpu_functions arm1176_cpufuncs = {
#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
struct cpu_functions cortexa_cpufuncs = {
/* CPU functions */
-
+
cpufunc_id, /* id */
cpufunc_nullop, /* cpwait */
-
+
/* MMU functions */
-
+
cpufunc_control, /* control */
cpufunc_domains, /* Domain */
armv7_setttb, /* Setttb */
cpufunc_faultstatus, /* Faultstatus */
cpufunc_faultaddress, /* Faultaddress */
-
- /*
+
+ /*
* TLB functions. ARMv7 does all TLB ops based on a unified TLB model
* whether the hardware implements separate I+D or not, so we use the
* same 'ID' functions for all 3 variations.
*/
-
+
armv7_tlb_flushID, /* tlb_flushID */
armv7_tlb_flushID_SE, /* tlb_flushID_SE */
armv7_tlb_flushID, /* tlb_flushI */
armv7_tlb_flushID_SE, /* tlb_flushI_SE */
armv7_tlb_flushID, /* tlb_flushD */
armv7_tlb_flushID_SE, /* tlb_flushD_SE */
-
+
/* Cache operations */
-
+
armv7_icache_sync_all, /* icache_sync_all */
armv7_icache_sync_range, /* icache_sync_range */
-
+
armv7_dcache_wbinv_all, /* dcache_wbinv_all */
armv7_dcache_wbinv_range, /* dcache_wbinv_range */
armv7_dcache_inv_range, /* dcache_inv_range */
armv7_dcache_wb_range, /* dcache_wb_range */
-
+
armv7_idcache_inv_all, /* idcache_inv_all */
armv7_idcache_wbinv_all, /* idcache_wbinv_all */
armv7_idcache_wbinv_range, /* idcache_wbinv_range */
-
- /*
+
+ /*
* Note: For CPUs using the PL310 the L2 ops are filled in when the
* L2 cache controller is actually enabled.
*/
@@ -665,23 +665,23 @@ struct cpu_functions cortexa_cpufuncs = {
(void *)cpufunc_nullop, /* l2cache_inv_range */
(void *)cpufunc_nullop, /* l2cache_wb_range */
(void *)cpufunc_nullop, /* l2cache_drain_writebuf */
-
+
/* Other functions */
-
+
cpufunc_nullop, /* flush_prefetchbuf */
armv7_drain_writebuf, /* drain_writebuf */
cpufunc_nullop, /* flush_brnchtgt_C */
(void *)cpufunc_nullop, /* flush_brnchtgt_E */
-
+
armv7_cpu_sleep, /* sleep */
-
+
/* Soft functions */
-
+
cpufunc_null_fixup, /* dataabt_fixup */
cpufunc_null_fixup, /* prefetchabt_fixup */
-
+
armv7_context_switch, /* context_switch */
-
+
cortexa_setup /* cpu setup */
};
#endif /* CPU_CORTEXA */
@@ -758,7 +758,7 @@ get_cachetype_cp15()
__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
: "=r" (csize));
arm_cache_type[sel] = csize;
- arm_dcache_align = 1 <<
+ arm_dcache_align = 1 <<
(CPUV7_CT_xSIZE_LEN(csize) + 4);
arm_dcache_align_mask = arm_dcache_align - 1;
}
@@ -913,12 +913,12 @@ set_cpufuncs()
cpufuncs = cortexa_cpufuncs;
cpu_reset_needs_v4_MMU_disable = 1; /* V4 or higher */
get_cachetype_cp15();
-
+
pmap_pte_init_mmu_v6();
goto out;
}
#endif /* CPU_CORTEXA */
-
+
#if defined(CPU_MV_PJ4B)
if (cputype == CPU_ID_MV88SV581X_V7 ||
cputype == CPU_ID_MV88SV584X_V7 ||
@@ -1116,37 +1116,20 @@ cpu_scc_setup_ccnt(void)
* you want!
*/
#ifdef _PMC_USER_READ_WRITE_
-#if defined(CPU_ARM1176)
- /* Use the Secure User and Non-secure Access Validation Control Register
- * to allow userland access
- */
- __asm volatile ("mcr p15, 0, %0, c15, c9, 0\n\t"
- :
- : "r"(0x00000001));
-#else
/* Set PMUSERENR[0] to allow userland access */
- __asm volatile ("mcr p15, 0, %0, c9, c14, 0\n\t"
- :
- : "r"(0x00000001));
-#endif
+ cp15_pmuserenr_set(1);
#endif
#if defined(CPU_ARM1176)
/* Set PMCR[2,0] to enable counters and reset CCNT */
- __asm volatile ("mcr p15, 0, %0, c15, c12, 0\n\t"
- :
- : "r"(0x00000005));
+ cp15_pmcr_set(5);
#else
/* Set up the PMCCNTR register as a cyclecounter:
* Set PMINTENCLR to 0xFFFFFFFF to block interrupts
* Set PMCR[2,0] to enable counters and reset CCNT
* Set PMCNTENSET to 0x80000000 to enable CCNT */
- __asm volatile ("mcr p15, 0, %0, c9, c14, 2\n\t"
- "mcr p15, 0, %1, c9, c12, 0\n\t"
- "mcr p15, 0, %2, c9, c12, 1\n\t"
- :
- : "r"(0xFFFFFFFF),
- "r"(0x00000005),
- "r"(0x80000000));
+ cp15_pminten_clr(0xFFFFFFFF);
+ cp15_pmcr_set(5);
+ cp15_pmcnten_set(0x80000000);
#endif
}
#endif
@@ -1182,7 +1165,7 @@ arm11x6_setup(void)
(3 << 30) | /* SBZ */
(1 << 29) | /* FA */
(1 << 28) | /* TR */
- (3 << 26) | /* SBZ */
+ (3 << 26) | /* SBZ */
(3 << 19) | /* SBZ */
(1 << 17); /* SBZ */
@@ -1214,19 +1197,18 @@ arm11x6_setup(void)
__asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz));
/* Allow detection code to find the VFP if it's fitted. */
- __asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff));
+ cp15_cpacr_set(0x0fffffff);
/* Set the control register */
ctrl = cpuctrl;
cpu_control(~cpuctrl_wax, cpuctrl);
- __asm volatile ("mrc p15, 0, %0, c1, c0, 1\n\t"
- "and %1, %0, %2\n\t"
- "orr %1, %1, %3\n\t"
- "teq %0, %1\n\t"
- "mcrne p15, 0, %1, c1, c0, 1\n\t"
- : "=r"(tmp), "=r"(tmp2) :
- "r"(auxctrl_wax), "r"(auxctrl));
+ tmp = cp15_actlr_get();
+ tmp2 = tmp;
+ tmp &= auxctrl_wax;
+ tmp |= auxctrl;
+ if (tmp != tmp2)
+ cp15_actlr_set(tmp);
/* And again. */
cpu_idcache_wbinv_all();
@@ -1276,39 +1258,39 @@ void
cortexa_setup(void)
{
int cpuctrl, cpuctrlmask;
-
+
cpuctrlmask = CPU_CONTROL_MMU_ENABLE | /* MMU enable [0] */
CPU_CONTROL_AFLT_ENABLE | /* Alignment fault [1] */
CPU_CONTROL_DC_ENABLE | /* DCache enable [2] */
CPU_CONTROL_BPRD_ENABLE | /* Branch prediction [11] */
CPU_CONTROL_IC_ENABLE | /* ICache enable [12] */
CPU_CONTROL_VECRELOC; /* Vector relocation [13] */
-
+
cpuctrl = CPU_CONTROL_MMU_ENABLE |
CPU_CONTROL_IC_ENABLE |
CPU_CONTROL_DC_ENABLE |
CPU_CONTROL_BPRD_ENABLE;
-
+
#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
#endif
-
+
/* Switch to big endian */
#ifdef __ARMEB__
cpuctrl |= CPU_CONTROL_BEND_ENABLE;
#endif
-
+
/* Check if the vector page is at the high address (0xffff0000) */
if (vector_page == ARM_VECTORS_HIGH)
cpuctrl |= CPU_CONTROL_VECRELOC;
-
+
/* Clear out the cache */
cpu_idcache_wbinv_all();
-
+
/* Set the control register */
ctrl = cpuctrl;
cpu_control(cpuctrlmask, cpuctrl);
-
+
/* And again. */
cpu_idcache_wbinv_all();
#ifdef SMP
diff --git a/sys/arm/arm/cpufunc_asm_arm11x6.S b/sys/arm/arm/cpufunc_asm_arm11x6.S
index 4d2697a687e5..b88c0fd67ee2 100644
--- a/sys/arm/arm/cpufunc_asm_arm11x6.S
+++ b/sys/arm/arm/cpufunc_asm_arm11x6.S
@@ -73,7 +73,7 @@ __FBSDID("$FreeBSD$");
*
* Erratum 411920 in ARM1136 (fixed in r1p4)
* Erratum 415045 in ARM1176 (fixed in r0p5?)
- *
+ *
* - value of arg 'reg' Should Be Zero
*/
#define Invalidate_I_cache(Rtmp1, Rtmp2) \
@@ -150,20 +150,20 @@ ENTRY_NP(arm11x6_icache_sync_range)
/* Erratum ARM1176 371367 */
mrs r2, cpsr /* save the CPSR */
cpsid ifa /* disable interrupts (irq,fiq,abort) */
- mov r3, #0
+ mov r3, #0
mcr p15, 0, r3, c13, c0, 0 /* write FCSE (uTLB invalidate) */
mcr p15, 0, r3, c7, c5, 4 /* flush prefetch buffer */
- add r3, pc, #0x24
+ add r3, pc, #0x24
mcr p15, 0, r3, c7, c13, 1 /* prefetch I-cache line */
mcrr p15, 0, r1, r0, c5 /* invalidate I-cache range */
msr cpsr_cx, r2 /* local_irq_restore */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
mcrr p15, 0, r1, r0, c12 /* clean and invalidate D cache range */ /* XXXNH */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
@@ -177,20 +177,20 @@ ENTRY_NP(arm11x6_idcache_wbinv_range)
/* Erratum ARM1176 371367 */
mrs r2, cpsr /* save the CPSR */
cpsid ifa /* disable interrupts (irq,fiq,abort) */
- mov r3, #0
+ mov r3, #0
mcr p15, 0, r3, c13, c0, 0 /* write FCSE (uTLB invalidate) */
mcr p15, 0, r3, c7, c5, 4 /* flush prefetch buffer */
- add r3, pc, #0x24
+ add r3, pc, #0x24
mcr p15, 0, r3, c7, c13, 1 /* prefetch I-cache line */
mcrr p15, 0, r1, r0, c5 /* invalidate I-cache range */
msr cpsr_cx, r2 /* local_irq_restore */
- nop
- nop
- nop
- nop
- nop
- nop
- nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
mcrr p15, 0, r1, r0, c14 /* clean and invalidate D cache range */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
@@ -199,7 +199,7 @@ END(arm11x6_idcache_wbinv_range)
/*
* Preload the cache before issuing the WFI by conditionally disabling the
- * mcr intstructions the first time around the loop. Ensure the function is
+ * mcr intstructions the first time around the loop. Ensure the function is
* cacheline aligned.
*/
.arch armv6
diff --git a/sys/arm/arm/cpufunc_asm_arm9.S b/sys/arm/arm/cpufunc_asm_arm9.S
index 24a314245030..9247b0c42b1c 100644
--- a/sys/arm/arm/cpufunc_asm_arm9.S
+++ b/sys/arm/arm/cpufunc_asm_arm9.S
@@ -130,7 +130,7 @@ ENTRY(arm9_dcache_wb_range)
bhi .Larm9_wb_next
mov pc, lr
END(arm9_dcache_wb_range)
-
+
ENTRY(arm9_dcache_wbinv_range)
ldr ip, .Larm9_line_size
cmp r1, #0x4000
@@ -147,7 +147,7 @@ ENTRY(arm9_dcache_wbinv_range)
bhi .Larm9_wbinv_next
mov pc, lr
END(arm9_dcache_wbinv_range)
-
+
/*
* Note, we must not invalidate everything. If the range is too big we
* must use wb-inv of the entire cache.
diff --git a/sys/arm/arm/cpufunc_asm_armv6.S b/sys/arm/arm/cpufunc_asm_armv6.S
index 7c111c7d1e56..7d3af6eb0593 100644
--- a/sys/arm/arm/cpufunc_asm_armv6.S
+++ b/sys/arm/arm/cpufunc_asm_armv6.S
@@ -37,7 +37,7 @@
/*
* $FreeBSD$
*/
-
+
#include <machine/asm.h>
.arch armv6
@@ -69,7 +69,7 @@ ENTRY(armv6_dcache_wb_range)
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(armv6_dcache_wb_range)
-
+
/* LINTSTUB: void armv6_dcache_wbinv_range(vaddr_t, vsize_t); */
ENTRY(armv6_dcache_wbinv_range)
add r1, r1, r0
@@ -78,7 +78,7 @@ ENTRY(armv6_dcache_wbinv_range)
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(armv6_dcache_wbinv_range)
-
+
/*
* Note, we must not invalidate everything. If the range is too big we
* must use wb-inv of the entire cache.
diff --git a/sys/arm/arm/cpufunc_asm_armv7.S b/sys/arm/arm/cpufunc_asm_armv7.S
index 1e7d7e2f0dc4..42ccc6dd47e2 100644
--- a/sys/arm/arm/cpufunc_asm_armv7.S
+++ b/sys/arm/arm/cpufunc_asm_armv7.S
@@ -64,7 +64,7 @@ __FBSDID("$FreeBSD$");
#define PT_OUTER_WT (2 << 3)
#define PT_OUTER_WB (3 << 3)
#define PT_OUTER_WBWA (1 << 3)
-
+
#ifdef SMP
#define PT_ATTR (PT_S|PT_INNER_WBWA|PT_OUTER_WBWA|PT_NOS)
#else
diff --git a/sys/arm/arm/cpufunc_asm_xscale_c3.S b/sys/arm/arm/cpufunc_asm_xscale_c3.S
index 78fa2d578dcf..cb770a8b873a 100644
--- a/sys/arm/arm/cpufunc_asm_xscale_c3.S
+++ b/sys/arm/arm/cpufunc_asm_xscale_c3.S
@@ -135,7 +135,7 @@ __FBSDID("$FreeBSD$");
ldr r4, .Lblock_userspace_access ; \
ldr ip, [r4] ; \
orr r0, ip, #1 ; \
- str r0, [r4]
+ str r0, [r4]
#define XSCALE_CACHE_CLEAN_UNBLOCK \
str ip, [r3] ; \
@@ -217,7 +217,7 @@ ENTRY(xscalec3_cache_syncI_rng)
CPWAIT_AND_RETURN(r0)
END(xscalec3_cache_syncI_rng)
-
+
ENTRY(xscalec3_cache_purgeD_rng)
cmp r1, #0x4000
diff --git a/sys/arm/arm/cpuinfo.c b/sys/arm/arm/cpuinfo.c
index d9899065361d..311eba1f6d22 100644
--- a/sys/arm/arm/cpuinfo.c
+++ b/sys/arm/arm/cpuinfo.c
@@ -48,7 +48,7 @@ void
cpuinfo_init(void)
{
- cpuinfo.midr = cp15_midr_get();
+ cpuinfo.midr = cp15_midr_get();
/* Test old version id schemes first */
if ((cpuinfo.midr & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD) {
if (CPU_ID_ISOLD(cpuinfo.midr)) {
@@ -74,7 +74,7 @@ cpuinfo_init(void)
/* non ARM -> must be new id scheme */
cpuinfo.architecture = (cpuinfo.midr >> 16) & 0x0F;
cpuinfo.revision = (cpuinfo.midr >> 20) & 0x0F;
- }
+ }
/* Parse rest of MIDR */
cpuinfo.implementer = (cpuinfo.midr >> 24) & 0xFF;
cpuinfo.part_number = (cpuinfo.midr >> 4) & 0xFFF;
@@ -86,11 +86,11 @@ cpuinfo_init(void)
cpuinfo.tlbtr = cp15_tlbtr_get();
cpuinfo.mpidr = cp15_mpidr_get();
cpuinfo.revidr = cp15_revidr_get();
-
+
/* if CPU is not v7 cpu id scheme */
if (cpuinfo.architecture != 0xF)
return;
-
+
cpuinfo.id_pfr0 = cp15_id_pfr0_get();
cpuinfo.id_pfr1 = cp15_id_pfr1_get();
cpuinfo.id_dfr0 = cp15_id_dfr0_get();
diff --git a/sys/arm/arm/db_interface.c b/sys/arm/arm/db_interface.c
index 690665087678..3a2515e7ad49 100644
--- a/sys/arm/arm/db_interface.c
+++ b/sys/arm/arm/db_interface.c
@@ -326,12 +326,9 @@ branch_taken(u_int insn, db_addr_t pc)
default:
break; /* XXX */
}
-
}
return (addr + offset);
-
}
-
case 0xa: /* b ... */
case 0xb: /* bl ... */
addr = ((insn << 2) & 0x03ffffff);
diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c
index 598decc3ff81..e5cc6a023240 100644
--- a/sys/arm/arm/elf_machdep.c
+++ b/sys/arm/arm/elf_machdep.c
@@ -81,6 +81,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
static Elf32_Brandinfo freebsd_brand_info = {
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c
index bdde6d6ce6e5..c3a7eeddfc93 100644
--- a/sys/arm/arm/elf_trampoline.c
+++ b/sys/arm/arm/elf_trampoline.c
@@ -93,7 +93,7 @@ extern void sheeva_l2cache_wbinv_all(void);
#define cpu_idcache_wbinv_all armv7_idcache_wbinv_all
#define cpu_l2cache_wbinv_all()
#else
-#define cpu_l2cache_wbinv_all()
+#define cpu_l2cache_wbinv_all()
#endif
static void armadaxp_idcache_wbinv_all(void);
@@ -216,7 +216,7 @@ _startC(void)
"mov sp, %1\n"
"mov pc, %0\n"
: : "r" (target_addr), "r" (tmp_sp));
-
+
}
#endif
#ifdef KZIP
@@ -225,7 +225,7 @@ _startC(void)
sp += 2 * L1_TABLE_SIZE;
#endif
sp += 1024 * 1024; /* Should be enough for a stack */
-
+
__asm __volatile("adr %0, 2f\n"
"bic %0, %0, #0xff000000\n"
"and %1, %1, #0xff000000\n"
@@ -366,7 +366,7 @@ get_cachetype_cp15()
static void
arm9_setup(void)
{
-
+
get_cachetype_cp15();
arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize +
@@ -490,7 +490,7 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
vm_offset_t lastaddr = 0;
Elf_Addr ssym = 0;
Elf_Dyn *dp;
-
+
eh = (Elf32_Ehdr *)kstart;
ssym = 0;
entry_point = (void*)eh->e_entry;
@@ -504,7 +504,7 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
lastaddr = phdr[i].p_vaddr - KERNVIRTADDR +
curaddr + phdr[i].p_memsz;
}
-
+
/* Save the symbol tables, as there're about to be scratched. */
memcpy(shdr, (void *)(kstart + eh->e_shoff),
sizeof(*shdr) * eh->e_shnum);
@@ -552,12 +552,12 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
lastaddr = roundup(lastaddr,
sizeof(shdr[symstrindex].sh_size));
}
-
+
}
}
if (!d)
return ((void *)lastaddr);
-
+
j = eh->e_phnum;
for (i = 0; i < j; i++) {
volatile char c;
@@ -610,7 +610,7 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end,
((void(*)(void))(entry_point - KERNVIRTADDR + curaddr))();
__asm __volatile(".globl func_end\n"
"func_end:");
-
+
/* NOTREACHED */
return NULL;
}
@@ -653,7 +653,7 @@ setup_pagetables(unsigned int pt_addr, vm_paddr_t physstart, vm_paddr_t physend,
"mov r0, r0\n"
"sub pc, pc, #4\n" :
"=r" (tmp) : "r" (pd), "r" (domain));
-
+
/*
* XXX: This is the most stupid workaround I've ever wrote.
* For some reason, the KB9202 won't boot the kernel unless
@@ -680,7 +680,7 @@ __start(void)
if (*kernel == 0x1f && kernel[1] == 0x8b) {
pt_addr = (((int)&_end + KERNSIZE + 0x100) &
~(L1_TABLE_SIZE - 1)) + L1_TABLE_SIZE;
-
+
#ifdef CPU_ARM9
/* So that idcache_wbinv works; */
if ((cpufunc_id() & 0x0000f000) == 0x00009000)
@@ -715,7 +715,7 @@ __start(void)
dst = (void *)(((vm_offset_t)dst & ~3));
pt_addr = ((unsigned int)dst &~(L1_TABLE_SIZE - 1)) + L1_TABLE_SIZE;
setup_pagetables(pt_addr, (vm_paddr_t)curaddr,
- (vm_paddr_t)curaddr + 0x10000000, 0);
+ (vm_paddr_t)curaddr + 0x10000000, 0);
sp = pt_addr + L1_TABLE_SIZE + 8192;
sp = sp &~3;
dst = (void *)(sp + 4);
@@ -725,7 +725,6 @@ __start(void)
(unsigned int)(&load_kernel) + 800, sp);
}
-#ifdef __ARM_EABI__
/* We need to provide these functions but never call them */
void __aeabi_unwind_cpp_pr0(void);
void __aeabi_unwind_cpp_pr1(void);
@@ -737,5 +736,3 @@ void
__aeabi_unwind_cpp_pr0(void)
{
}
-#endif
-
diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S
index b85dcfc793f6..5f1dff7ec03e 100644
--- a/sys/arm/arm/exception.S
+++ b/sys/arm/arm/exception.S
@@ -49,6 +49,7 @@
#include "assym.s"
#include "opt_kdtrace.h"
+#include <machine/acle-compat.h>
#include <machine/asm.h>
#include <machine/armreg.h>
#include <machine/asmacros.h>
@@ -63,7 +64,7 @@ _C_LABEL(dtrace_invop_calltrap_addr):
.word 0
#endif
- .text
+ .text
.align 2
/*
@@ -80,7 +81,7 @@ _C_LABEL(dtrace_invop_calltrap_addr):
* NOTE: r13 and r14 are stored separately as a work around for the
* SA110 rev 2 STM^ bug
*/
-#ifdef ARM_TP_ADDRESS
+#if __ARM_ARCH < 6
#define PUSHFRAME \
sub sp, sp, #4; /* Align the stack */ \
str lr, [sp, #-4]!; /* Push the return address */ \
@@ -114,7 +115,7 @@ _C_LABEL(dtrace_invop_calltrap_addr):
* Since the current mode is used, the SVC lr field is ignored.
*/
-#ifdef ARM_TP_ADDRESS
+#if __ARM_ARCH < 6
#define PULLFRAME \
ldr r0, [sp], #4; /* Get the SPSR from stack */ \
msr spsr_fsxc, r0; \
@@ -123,7 +124,7 @@ _C_LABEL(dtrace_invop_calltrap_addr):
add sp, sp, #(4*17); /* Adjust the stack pointer */ \
ldr lr, [sp], #4; /* Pull the return address */ \
add sp, sp, #4 /* Align the stack */
-#else
+#else
#define PULLFRAME \
ldr r0, [sp], #4 ; /* Get the SPSR from stack */ \
msr spsr_fsxc, r0; \
@@ -145,7 +146,7 @@ _C_LABEL(dtrace_invop_calltrap_addr):
* NOTE: r13 and r14 are stored separately as a work around for the
* SA110 rev 2 STM^ bug
*/
-#ifdef ARM_TP_ADDRESS
+#if __ARM_ARCH < 6
#define PUSHFRAMEINSVC \
stmdb sp, {r0-r3}; /* Save 4 registers */ \
mov r0, lr; /* Save xxx32 r14 */ \
@@ -218,7 +219,7 @@ _C_LABEL(dtrace_invop_calltrap_addr):
* exit.
*/
-#ifdef ARM_TP_ADDRESS
+#if __ARM_ARCH < 6
#define PULLFRAMEFROMSVCANDEXIT \
ldr r0, [sp], #4; /* Get the SPSR from stack */ \
msr spsr_fsxc, r0; /* restore SPSR */ \
@@ -226,7 +227,7 @@ _C_LABEL(dtrace_invop_calltrap_addr):
mov r0, r0; /* NOP for previous instruction */ \
add sp, sp, #(4*15); /* Adjust the stack pointer */ \
ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */
-#else
+#else
#define PULLFRAMEFROMSVCANDEXIT \
ldr r0, [sp], #4; /* Get the SPSR from stack */ \
msr spsr_fsxc, r0; /* restore SPSR */ \
@@ -237,7 +238,6 @@ _C_LABEL(dtrace_invop_calltrap_addr):
ldmia sp, {sp, lr, pc}^ /* Restore lr and exit */
#endif
-#if defined(__ARM_EABI__)
/*
* Unwind hints so we can unwind past functions that use
* PULLFRAMEFROMSVCANDEXIT. They are run in reverse order.
@@ -249,9 +249,6 @@ _C_LABEL(dtrace_invop_calltrap_addr):
.pad #(2*4); /* Skip user sp and lr */ \
.save {r0-r12}; /* Restore r0-r12 */ \
.pad #(4) /* Skip spsr */
-#else
-#define UNWINDSVCFRAME
-#endif
#define DO_AST \
ldr r0, [sp]; /* Get the SPSR from stack */ \
@@ -320,7 +317,7 @@ END(exception_exit)
* Entry point for a Prefetch Abort exception.
*
* The hardware switches to the abort mode stack; we switch to svc32 before
- * calling the handler, then return directly to the original mode/stack
+ * calling the handler, then return directly to the original mode/stack
* on exit (without transitioning back through the abort mode stack).
*/
ASENTRY_NP(prefetch_abort_entry)
@@ -340,7 +337,7 @@ END(prefetch_abort_entry)
* Entry point for a Data Abort exception.
*
* The hardware switches to the abort mode stack; we switch to svc32 before
- * calling the handler, then return directly to the original mode/stack
+ * calling the handler, then return directly to the original mode/stack
* on exit (without transitioning back through the abort mode stack).
*/
ASENTRY_NP(data_abort_entry)
@@ -360,7 +357,7 @@ END(data_abort_entry)
* Entry point for an Undefined Instruction exception.
*
* The hardware switches to the undefined mode stack; we switch to svc32 before
- * calling the handler, then return directly to the original mode/stack
+ * calling the handler, then return directly to the original mode/stack
* on exit (without transitioning back through the undefined mode stack).
*/
ASENTRY_NP(undefined_entry)
@@ -374,7 +371,7 @@ END(undefined_entry)
* Entry point for a normal IRQ.
*
* The hardware switches to the IRQ mode stack; we switch to svc32 before
- * calling the handler, then return directly to the original mode/stack
+ * calling the handler, then return directly to the original mode/stack
* on exit (without transitioning back through the IRQ mode stack).
*/
ASENTRY_NP(irq_entry)
@@ -383,12 +380,12 @@ ASENTRY_NP(irq_entry)
adr lr, exception_exit /* Return from handler via standard */
mov r0, sp /* exception exit routine. Pass the */
b _C_LABEL(arm_irq_handler)/* trapframe to the handler. */
-END(irq_entry)
+END(irq_entry)
/*
* Entry point for an FIQ interrupt.
*
- * We don't currently support FIQ handlers very much. Something can
+ * We don't currently support FIQ handlers very much. Something can
* install itself in the FIQ vector using code (that may or may not work
* these days) in fiq.c. If nobody does that and an FIQ happens, this
* default handler just disables FIQs and otherwise ignores it.
@@ -416,7 +413,7 @@ Laddr_exception_msg:
END(addr_exception_entry)
/*
- * Entry point for the system Reset vector.
+ * Entry point for the system Reset vector.
* This should never happen, so panic.
*/
ASENTRY_NP(reset_entry)
@@ -434,8 +431,8 @@ END(reset_entry)
* the ARM vectors page (high or low) as part of CPU initialization. The
* code that does the copy assumes that page0_data holds one 32-bit word
* of data for each of the predefined ARM vectors. It also assumes that
- * page0_data follows the vectors in page0, but other stuff can appear
- * between the two. We currently leave room between the two for some fiq
+ * page0_data follows the vectors in page0, but other stuff can appear
+ * between the two. We currently leave room between the two for some fiq
* handler code to be copied in.
*/
.global _C_LABEL(page0), _C_LABEL(page0_data)
diff --git a/sys/arm/arm/fiq.c b/sys/arm/arm/fiq.c
index 08f867083e9e..94231dea22c8 100644
--- a/sys/arm/arm/fiq.c
+++ b/sys/arm/arm/fiq.c
@@ -59,7 +59,7 @@ extern uint32_t fiq_nullhandler_size;
* fiq_installhandler:
*
* Actually install the FIQ handler down at the FIQ vector.
- *
+ *
* The FIQ vector is fixed by the hardware definition as the
* seventh 32-bit word in the vector page.
*
diff --git a/sys/arm/arm/fusu.S b/sys/arm/arm/fusu.S
index ab7fb58301b5..06853c456948 100644
--- a/sys/arm/arm/fusu.S
+++ b/sys/arm/arm/fusu.S
@@ -70,11 +70,11 @@ EENTRY_NP(casuword32)
adr r4, .Lcasuwordfault
str r4, [r3, #PCB_ONFAULT]
#if __ARM_ARCH >= 6
-1:
+1:
cmp r0, #KERNBASE
mvnhs r0, #0
bhs 2f
-
+
ldrex r5, [r0]
cmp r5, r1
movne r0, r5
@@ -106,7 +106,7 @@ END(casuword)
str r0, [r3, #PCB_ONFAULT]
mvn r0, #0x00000000
ldmfd sp!, {r4, r5}
- RET
+ RET
/*
* fuword(caddr_t uaddr);
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c
index 3301ce156d51..11bb90fb2953 100644
--- a/sys/arm/arm/genassym.c
+++ b/sys/arm/arm/genassym.c
@@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
+
+#include <machine/acle-compat.h>
#include <machine/vmparam.h>
#include <machine/armreg.h>
#include <machine/frame.h>
@@ -124,7 +126,7 @@ ASSYM(P_FLAG, offsetof(struct proc, p_flag));
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
-#ifdef ARM_TP_ADDRESS
+#if __ARM_ARCH < 6
ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
ASSYM(ARM_RAS_START, ARM_RAS_START);
ASSYM(ARM_RAS_END, ARM_RAS_END);
@@ -133,8 +135,6 @@ ASSYM(ARM_RAS_END, ARM_RAS_END);
#ifdef VFP
ASSYM(PCB_VFPSTATE, offsetof(struct pcb, pcb_vfpstate));
-ASSYM(PC_CPU, offsetof(struct pcpu, pc_cpu));
-
ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
#endif
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 56db9cadfe2e..636ba7502e68 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -34,6 +34,9 @@
* Cortex-A7, Cortex-A15, ARMv8 and later Generic Timer
*/
+#include "opt_acpi.h"
+#include "opt_platform.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -51,12 +54,17 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <machine/intr.h>
+#ifdef FDT
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
+#endif
-#include <machine/bus.h>
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+#endif
#define GT_CTRL_ENABLE (1 << 0)
#define GT_CTRL_INT_MASK (1 << 1)
@@ -247,8 +255,9 @@ arm_tmr_intr(void *arg)
return (FILTER_HANDLED);
}
+#ifdef FDT
static int
-arm_tmr_probe(device_t dev)
+arm_tmr_fdt_probe(device_t dev)
{
if (!ofw_bus_status_okay(dev))
@@ -264,14 +273,62 @@ arm_tmr_probe(device_t dev)
return (ENXIO);
}
+#endif
+
+#ifdef DEV_ACPI
+static void
+arm_tmr_acpi_identify(driver_t *driver, device_t parent)
+{
+ ACPI_TABLE_GTDT *gtdt;
+ vm_paddr_t physaddr;
+ device_t dev;
+
+ physaddr = acpi_find_table(ACPI_SIG_GTDT);
+ if (physaddr == 0)
+ return;
+
+ gtdt = acpi_map_table(physaddr, ACPI_SIG_GTDT);
+ if (gtdt == NULL) {
+ device_printf(parent, "gic: Unable to map the GTDT\n");
+ return;
+ }
+
+ dev = BUS_ADD_CHILD(parent, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE,
+ "generic_timer", -1);
+ if (dev == NULL) {
+ device_printf(parent, "add gic child failed\n");
+ goto out;
+ }
+
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 0,
+ gtdt->SecureEl1Interrupt, 1);
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 1,
+ gtdt->NonSecureEl1Interrupt, 1);
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 2,
+ gtdt->VirtualTimerInterrupt, 1);
+
+out:
+ acpi_unmap_table(gtdt);
+}
+
+static int
+arm_tmr_acpi_probe(device_t dev)
+{
+
+ device_set_desc(dev, "ARM Generic Timer");
+ return (BUS_PROBE_NOWILDCARD);
+}
+#endif
static int
arm_tmr_attach(device_t dev)
{
struct arm_tmr_softc *sc;
+#ifdef FDT
phandle_t node;
pcell_t clock;
+#endif
int error;
int i;
@@ -279,12 +336,17 @@ arm_tmr_attach(device_t dev)
if (arm_tmr_sc)
return (ENXIO);
+#ifdef FDT
/* Get the base clock frequency */
node = ofw_bus_get_node(dev);
- error = OF_getprop(node, "clock-frequency", &clock, sizeof(clock));
- if (error > 0) {
- sc->clkfreq = fdt32_to_cpu(clock);
+ if (node > 0) {
+ error = OF_getprop(node, "clock-frequency", &clock,
+ sizeof(clock));
+ if (error > 0) {
+ sc->clkfreq = fdt32_to_cpu(clock);
+ }
}
+#endif
if (sc->clkfreq == 0) {
/* Try to get clock frequency from timer */
@@ -339,24 +401,46 @@ arm_tmr_attach(device_t dev)
return (0);
}
-static device_method_t arm_tmr_methods[] = {
- DEVMETHOD(device_probe, arm_tmr_probe),
+#ifdef FDT
+static device_method_t arm_tmr_fdt_methods[] = {
+ DEVMETHOD(device_probe, arm_tmr_fdt_probe),
DEVMETHOD(device_attach, arm_tmr_attach),
{ 0, 0 }
};
-static driver_t arm_tmr_driver = {
+static driver_t arm_tmr_fdt_driver = {
"generic_timer",
- arm_tmr_methods,
+ arm_tmr_fdt_methods,
sizeof(struct arm_tmr_softc),
};
-static devclass_t arm_tmr_devclass;
+static devclass_t arm_tmr_fdt_devclass;
-EARLY_DRIVER_MODULE(timer, simplebus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
- BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
-EARLY_DRIVER_MODULE(timer, ofwbus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
- BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(timer, simplebus, arm_tmr_fdt_driver, arm_tmr_fdt_devclass,
+ 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(timer, ofwbus, arm_tmr_fdt_driver, arm_tmr_fdt_devclass,
+ 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+#endif
+
+#ifdef DEV_ACPI
+static device_method_t arm_tmr_acpi_methods[] = {
+ DEVMETHOD(device_identify, arm_tmr_acpi_identify),
+ DEVMETHOD(device_probe, arm_tmr_acpi_probe),
+ DEVMETHOD(device_attach, arm_tmr_attach),
+ { 0, 0 }
+};
+
+static driver_t arm_tmr_acpi_driver = {
+ "generic_timer",
+ arm_tmr_acpi_methods,
+ sizeof(struct arm_tmr_softc),
+};
+
+static devclass_t arm_tmr_acpi_devclass;
+
+EARLY_DRIVER_MODULE(timer, acpi, arm_tmr_acpi_driver, arm_tmr_acpi_devclass,
+ 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+#endif
void
DELAY(int usec)
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index 45fb903e25af..6fcb7e082215 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -197,8 +197,8 @@ gic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
static u_int num_intr_cells;
if (num_intr_cells == 0) {
- if (OF_searchencprop(OF_node_from_xref(iparent),
- "#interrupt-cells", &num_intr_cells,
+ if (OF_searchencprop(OF_node_from_xref(iparent),
+ "#interrupt-cells", &num_intr_cells,
sizeof(num_intr_cells)) == -1) {
num_intr_cells = 1;
}
diff --git a/sys/arm/arm/intr.c b/sys/arm/arm/intr.c
index 950591537b4d..7ab87cc784eb 100644
--- a/sys/arm/arm/intr.c
+++ b/sys/arm/arm/intr.c
@@ -149,7 +149,7 @@ arm_setup_irqhandler(const char *name, driver_filter_t *filt,
if (error)
return;
intr_events[irq] = event;
- snprintf(&intrnames[irq * INTRNAME_LEN], INTRNAME_LEN,
+ snprintf(&intrnames[irq * INTRNAME_LEN], INTRNAME_LEN,
"irq%d: %-*s", irq, INTRNAME_LEN - 1, name);
}
intr_event_add_handler(event, name, filt, hand, arg,
@@ -164,7 +164,7 @@ arm_remove_irqhandler(int irq, void *cookie)
event = intr_events[irq];
arm_mask_irq(irq);
-
+
error = intr_event_remove_handler(cookie);
if (!TAILQ_EMPTY(&event->ie_handlers))
diff --git a/sys/arm/arm/locore-v4.S b/sys/arm/arm/locore-v4.S
index d798e97d7ff7..cc4f6361d67f 100644
--- a/sys/arm/arm/locore-v4.S
+++ b/sys/arm/arm/locore-v4.S
@@ -49,8 +49,7 @@ __FBSDID("$FreeBSD$");
*
* TODO: Fix the ARMv4/v5 case.
*/
-#if (defined(FLASHADDR) || defined(LOADERRAMADDR) || !defined(_ARM_ARCH_6)) && \
- !defined(PHYSADDR)
+#ifndef PHYSADDR
#error PHYSADDR must be defined for this configuration
#endif
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 01e8fe3f8034..99d45722c17f 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/cons.h>
#include <sys/cpu.h>
+#include <sys/efi.h>
#include <sys/exec.h>
#include <sys/imgact.h>
#include <sys/kdb.h>
@@ -71,6 +72,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/pcpu.h>
#include <sys/ptrace.h>
+#include <sys/reboot.h>
#include <sys/rwlock.h>
#include <sys/sched.h>
#include <sys/signalvar.h>
@@ -245,7 +247,7 @@ void
board_set_serial(uint64_t serial)
{
- snprintf(board_serial, sizeof(board_serial)-1,
+ snprintf(board_serial, sizeof(board_serial)-1,
"%016jx", serial);
}
@@ -297,7 +299,7 @@ sendsig(catcher, ksi, mask)
/* make room on the stack */
fp--;
-
+
/* make the stack aligned */
fp = (struct sigframe *)STACKALIGN(fp);
/* Populate the siginfo frame. */
@@ -318,17 +320,13 @@ sendsig(catcher, ksi, mask)
sigexit(td, SIGILL);
}
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
/*
* Build context to run handler in. We invoke the handler
* directly, only returning via the trampoline. Note the
* trampoline version numbers are coordinated with machine-
* dependent code in libc.
*/
-
+
tf->tf_r0 = sig;
tf->tf_r1 = (register_t)&fp->sf_si;
tf->tf_r2 = (register_t)&fp->sf_uc;
@@ -430,7 +428,7 @@ cpu_startup(void *dummy)
/*
* Display the RAM layout.
*/
- printf("real memory = %ju (%ju MB)\n",
+ printf("real memory = %ju (%ju MB)\n",
(uintmax_t)arm32_ptob(realmem),
(uintmax_t)arm32_ptob(realmem) / mbyte);
printf("avail memory = %ju (%ju MB)\n",
@@ -492,7 +490,7 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
void
cpu_idle(int busy)
{
-
+
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d", busy, curcpu);
spinlock_enter();
#ifndef NO_EVENTTIMERS
@@ -562,14 +560,14 @@ int
set_regs(struct thread *td, struct reg *regs)
{
struct trapframe *tf = td->td_frame;
-
+
bcopy(regs->r, &tf->tf_r0, sizeof(regs->r));
tf->tf_usr_sp = regs->r_sp;
tf->tf_usr_lr = regs->r_lr;
tf->tf_pc = regs->r_pc;
tf->tf_spsr &= ~PSR_FLAGS;
tf->tf_spsr |= regs->r_cpsr & PSR_FLAGS;
- return (0);
+ return (0);
}
int
@@ -633,7 +631,7 @@ ptrace_single_step(struct thread *td)
{
struct proc *p;
int error;
-
+
/* TODO: This needs to be updated for Thumb-2 */
if ((td->td_frame->tf_spsr & PSR_T) != 0)
return (EINVAL);
@@ -743,10 +741,13 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
struct trapframe *tf = td->td_frame;
__greg_t *gr = mcp->__gregs;
- if (clear_ret & GET_MC_CLEAR_RET)
+ if (clear_ret & GET_MC_CLEAR_RET) {
gr[_REG_R0] = 0;
- else
+ gr[_REG_CPSR] = tf->tf_spsr & ~PSR_C;
+ } else {
gr[_REG_R0] = tf->tf_r0;
+ gr[_REG_CPSR] = tf->tf_spsr;
+ }
gr[_REG_R1] = tf->tf_r1;
gr[_REG_R2] = tf->tf_r2;
gr[_REG_R3] = tf->tf_r3;
@@ -762,7 +763,6 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
gr[_REG_SP] = tf->tf_usr_sp;
gr[_REG_LR] = tf->tf_usr_lr;
gr[_REG_PC] = tf->tf_pc;
- gr[_REG_CPSR] = tf->tf_spsr;
return (0);
}
@@ -812,7 +812,7 @@ sys_sigreturn(td, uap)
{
ucontext_t uc;
int spsr;
-
+
if (uap == NULL)
return (EFAULT);
if (copyin(uap->sigcntxp, &uc, sizeof(uc)))
@@ -911,14 +911,11 @@ fake_preload_metadata(struct arm_boot_params *abp __unused)
void
pcpu0_init(void)
{
-#if ARM_ARCH_6 || ARM_ARCH_7A || defined(CPU_MV_PJ4B)
+#if __ARM_ARCH >= 6
set_curthread(&thread0);
#endif
pcpu_init(pcpup, 0, sizeof(struct pcpu));
PCPU_SET(curthread, &thread0);
-#ifdef VFP
- PCPU_SET(cpu, 0);
-#endif
}
#if defined(LINUX_BOOT_ABI)
@@ -1102,6 +1099,113 @@ set_stackptrs(int cpu)
}
#endif
+#ifdef EFI
+#define efi_next_descriptor(ptr, size) \
+ ((struct efi_md *)(((uint8_t *) ptr) + size))
+
+static void
+add_efi_map_entries(struct efi_map_header *efihdr, struct mem_region *mr,
+ int *mrcnt, uint32_t *memsize)
+{
+ struct efi_md *map, *p;
+ const char *type;
+ size_t efisz, memory_size;
+ int ndesc, i, j;
+
+ static const char *types[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode"
+ };
+
+ *mrcnt = 0;
+ *memsize = 0;
+
+ /*
+ * Memory map data provided by UEFI via the GetMemoryMap
+ * Boot Services API.
+ */
+ efisz = roundup2(sizeof(struct efi_map_header), 0x10);
+ map = (struct efi_md *)((uint8_t *)efihdr + efisz);
+
+ if (efihdr->descriptor_size == 0)
+ return;
+ ndesc = efihdr->memory_size / efihdr->descriptor_size;
+
+ if (boothowto & RB_VERBOSE)
+ printf("%23s %12s %12s %8s %4s\n",
+ "Type", "Physical", "Virtual", "#Pages", "Attr");
+
+ memory_size = 0;
+ for (i = 0, j = 0, p = map; i < ndesc; i++,
+ p = efi_next_descriptor(p, efihdr->descriptor_size)) {
+ if (boothowto & RB_VERBOSE) {
+ if (p->md_type <= EFI_MD_TYPE_PALCODE)
+ type = types[p->md_type];
+ else
+ type = "<INVALID>";
+ printf("%23s %012llx %12p %08llx ", type, p->md_phys,
+ p->md_virt, p->md_pages);
+ if (p->md_attr & EFI_MD_ATTR_UC)
+ printf("UC ");
+ if (p->md_attr & EFI_MD_ATTR_WC)
+ printf("WC ");
+ if (p->md_attr & EFI_MD_ATTR_WT)
+ printf("WT ");
+ if (p->md_attr & EFI_MD_ATTR_WB)
+ printf("WB ");
+ if (p->md_attr & EFI_MD_ATTR_UCE)
+ printf("UCE ");
+ if (p->md_attr & EFI_MD_ATTR_WP)
+ printf("WP ");
+ if (p->md_attr & EFI_MD_ATTR_RP)
+ printf("RP ");
+ if (p->md_attr & EFI_MD_ATTR_XP)
+ printf("XP ");
+ if (p->md_attr & EFI_MD_ATTR_RT)
+ printf("RUNTIME");
+ printf("\n");
+ }
+
+ switch (p->md_type) {
+ case EFI_MD_TYPE_CODE:
+ case EFI_MD_TYPE_DATA:
+ case EFI_MD_TYPE_BS_CODE:
+ case EFI_MD_TYPE_BS_DATA:
+ case EFI_MD_TYPE_FREE:
+ /*
+ * We're allowed to use any entry with these types.
+ */
+ break;
+ default:
+ continue;
+ }
+
+ j++;
+ if (j >= FDT_MEM_REGIONS)
+ break;
+
+ mr[j].mr_start = p->md_phys;
+ mr[j].mr_size = p->md_pages * PAGE_SIZE;
+ memory_size += mr[j].mr_size;
+ }
+
+ *mrcnt = j;
+ *memsize = memory_size;
+}
+#endif /* EFI */
+
#ifdef FDT
static char *
kenv_next(char *cp)
@@ -1186,7 +1290,7 @@ initarm(struct arm_boot_params *abp)
/* Grab reserved memory regions information from device tree. */
if (fdt_get_reserved_regions(mem_regions, &mem_regions_sz) == 0)
- arm_physmem_exclude_regions(mem_regions, mem_regions_sz,
+ arm_physmem_exclude_regions(mem_regions, mem_regions_sz,
EXFLAG_NODUMP | EXFLAG_NOALLOC);
/* Platform-specific initialisation */
@@ -1392,7 +1496,7 @@ initarm(struct arm_boot_params *abp)
*
* Prepare the list of physical memory available to the vm subsystem.
*/
- arm_physmem_exclude_region(abp->abp_physaddr,
+ arm_physmem_exclude_region(abp->abp_physaddr,
(virtual_avail - KERNVIRTADDR), EXFLAG_NOALLOC);
arm_physmem_init_kernel_globals();
@@ -1413,6 +1517,9 @@ initarm(struct arm_boot_params *abp)
char *env;
void *kmdp;
int err_devmap, mem_regions_sz;
+#ifdef EFI
+ struct efi_map_header *efihdr;
+#endif
/* get last allocated physical address */
arm_physmem_kernaddr = abp->abp_physaddr;
@@ -1445,9 +1552,20 @@ initarm(struct arm_boot_params *abp)
if (OF_init((void *)dtbp) != 0)
panic("OF_init failed with the found device tree");
- /* Grab physical memory regions information from device tree. */
- if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, &memsize) != 0)
- panic("Cannot get physical memory regions");
+#ifdef EFI
+ efihdr = (struct efi_map_header *)preload_search_info(kmdp,
+ MODINFO_METADATA | MODINFOMD_EFI_MAP);
+ if (efihdr != NULL) {
+ add_efi_map_entries(efihdr, mem_regions, &mem_regions_sz,
+ &memsize);
+ } else
+#endif
+ {
+ /* Grab physical memory regions information from device tree. */
+ if (fdt_get_mem_regions(mem_regions, &mem_regions_sz,
+ &memsize) != 0)
+ panic("Cannot get physical memory regions");
+ }
arm_physmem_hardware_regions(mem_regions, mem_regions_sz);
/* Grab reserved memory regions information from device tree. */
diff --git a/sys/arm/arm/mp_machdep.c b/sys/arm/arm/mp_machdep.c
index 88104f0c3b2d..083e62efb8f4 100644
--- a/sys/arm/arm/mp_machdep.c
+++ b/sys/arm/arm/mp_machdep.c
@@ -197,8 +197,6 @@ init_secondary(int cpu)
pc->pc_curpcb = pc->pc_idlethread->td_pcb;
set_curthread(pc->pc_idlethread);
#ifdef VFP
- pc->pc_cpu = cpu;
-
vfp_init();
#endif
@@ -222,7 +220,7 @@ init_secondary(int cpu)
end = IPI_IRQ_START;
#endif
#endif
-
+
for (int i = start; i <= end; i++)
arm_unmask_irq(i);
enable_interrupts(PSR_I);
@@ -344,7 +342,7 @@ release_aps(void *dummy __unused)
/*
* IPI handler
*/
- /*
+ /*
* Use 0xdeadbeef as the argument value for irq 0,
* if we used 0, the intr code will give the trap frame
* pointer instead.
diff --git a/sys/arm/arm/mpcore_timer.c b/sys/arm/arm/mpcore_timer.c
index 88060cf45ac3..fb30d38f68a1 100644
--- a/sys/arm/arm/mpcore_timer.c
+++ b/sys/arm/arm/mpcore_timer.c
@@ -414,7 +414,7 @@ arm_tmr_attach(device_t dev)
if (!arm_tmr_freq_varies)
tc_err = attach_tc(sc);
else if (bootverbose)
- device_printf(sc->dev,
+ device_printf(sc->dev,
"not using variable-frequency device as timecounter");
sc->memrid++;
sc->irqrid++;
@@ -488,7 +488,7 @@ arm_tmr_change_frequency(uint64_t newfreq)
* @usec: number of microseconds to delay by
*
* This function is called all over the kernel and is suppose to provide a
- * consistent delay. This function may also be called before the console
+ * consistent delay. This function may also be called before the console
* is setup so no printf's can be called here.
*
* RETURNS:
diff --git a/sys/arm/arm/nexus.c b/sys/arm/arm/nexus.c
index 06f2d6ff454f..def6c1ad3cc4 100644
--- a/sys/arm/arm/nexus.c
+++ b/sys/arm/arm/nexus.c
@@ -127,7 +127,7 @@ static driver_t nexus_driver = {
nexus_methods,
1 /* no softc */
};
-EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0,
+EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0,
BUS_PASS_BUS + BUS_PASS_ORDER_EARLY);
static int
@@ -236,7 +236,7 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
int error;
-
+
if (rman_get_flags(res) & RF_ACTIVE) {
error = bus_deactivate_resource(child, type, rid, res);
if (error)
diff --git a/sys/arm/arm/physmem.c b/sys/arm/arm/physmem.c
index bc72ce264ad5..a92216337949 100644
--- a/sys/arm/arm/physmem.c
+++ b/sys/arm/arm/physmem.c
@@ -62,7 +62,7 @@ static size_t hwcnt;
static size_t excnt;
/*
- * These "avail lists" are globals used to communicate physical memory layout to
+ * These "avail lists" are globals used to communicate physical memory layout to
* other parts of the kernel. Within the arrays, each value is the starting
* address of a contiguous area of physical address space. The values at even
* indexes are areas that contain usable memory and the values at odd indexes
diff --git a/sys/arm/arm/pl190.c b/sys/arm/arm/pl190.c
index 5e811343b413..8cd744e6c993 100644
--- a/sys/arm/arm/pl190.c
+++ b/sys/arm/arm/pl190.c
@@ -121,7 +121,7 @@ pl190_intc_attach(device_t dev)
id = 0;
for (i = 3; i >= 0; i--) {
- id = (id << 8) |
+ id = (id << 8) |
(intc_vic_read_4(VICPERIPHID + i*4) & 0xff);
}
@@ -129,7 +129,7 @@ pl190_intc_attach(device_t dev)
id = 0;
for (i = 3; i >= 0; i--) {
- id = (id << 8) |
+ id = (id << 8) |
(intc_vic_read_4(VICPRIMECELLID + i*4) & 0xff);
}
@@ -152,7 +152,7 @@ static driver_t pl190_intc_driver = {
static devclass_t pl190_intc_devclass;
-EARLY_DRIVER_MODULE(intc, simplebus, pl190_intc_driver, pl190_intc_devclass,
+EARLY_DRIVER_MODULE(intc, simplebus, pl190_intc_driver, pl190_intc_devclass,
0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
int
@@ -164,7 +164,7 @@ arm_get_next_irq(int last_irq)
/* Sanity check */
if (irq < 0)
irq = 0;
-
+
pending = intc_vic_read_4(VICIRQSTATUS);
while (irq < VIC_NIRQS) {
if (pending & (1 << irq))
diff --git a/sys/arm/arm/pl310.c b/sys/arm/arm/pl310.c
index 3305f35c80f8..2fba6a837416 100644
--- a/sys/arm/arm/pl310.c
+++ b/sys/arm/arm/pl310.c
@@ -50,11 +50,11 @@ __FBSDID("$FreeBSD$");
/*
* Define this if you need to disable PL310 for debugging purpose
- * Spec:
+ * Spec:
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0246e/DDI0246E_l2c310_r3p1_trm.pdf
*/
-/*
+/*
* Hardcode errata for now
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0246b/pr01s02s02.html
*/
@@ -137,7 +137,7 @@ pl310_set_ram_latency(struct pl310_softc *sc, uint32_t which_reg,
{
uint32_t v;
- KASSERT(which_reg == PL310_TAG_RAM_CTRL ||
+ KASSERT(which_reg == PL310_TAG_RAM_CTRL ||
which_reg == PL310_DATA_RAM_CTRL,
("bad pl310 ram latency register address"));
@@ -191,7 +191,7 @@ pl310_wait_background_op(uint32_t off, uint32_t mask)
/**
* pl310_cache_sync - performs a cache sync operation
- *
+ *
* According to the TRM:
*
* "Before writing to any other register you must perform an explicit
@@ -231,7 +231,7 @@ pl310_wbinv_all(void)
for (i = 0; i < g_ways_assoc; i++) {
for (j = 0; j < g_way_size / g_l2cache_line_size; j++) {
- pl310_write4(pl310_softc,
+ pl310_write4(pl310_softc,
PL310_CLEAN_INV_LINE_IDX,
(i << 28 | j << 5));
}
@@ -278,8 +278,8 @@ pl310_wbinv_range(vm_paddr_t start, vm_size_t size)
while (size > 0) {
#ifdef PL310_ERRATA_588369
if (pl310_softc->sc_rtl_revision <= CACHE_ID_RELEASE_r1p0) {
- /*
- * Errata 588369 says that clean + inv may keep the
+ /*
+ * Errata 588369 says that clean + inv may keep the
* cache line if it was clean, the recommanded
* workaround is to clean then invalidate the cache
* line, with write-back and cache linefill disabled.
@@ -402,10 +402,10 @@ pl310_config_intr(void *arg)
pl310_filter, NULL, sc, &sc->sc_irq_h);
/* Cache Line Eviction for Counter 0 */
- pl310_write4(sc, PL310_EVENT_COUNTER0_CONF,
+ pl310_write4(sc, PL310_EVENT_COUNTER0_CONF,
EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_CO);
/* Data Read Request for Counter 1 */
- pl310_write4(sc, PL310_EVENT_COUNTER1_CONF,
+ pl310_write4(sc, PL310_EVENT_COUNTER1_CONF,
EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_DRREQ);
/* Enable and clear pending interrupts */
@@ -413,9 +413,9 @@ pl310_config_intr(void *arg)
pl310_write4(sc, PL310_INTR_MASK, INTR_MASK_ALL);
/* Enable counters and reset C0 and C1 */
- pl310_write4(sc, PL310_EVENT_COUNTER_CTRL,
- EVENT_COUNTER_CTRL_ENABLED |
- EVENT_COUNTER_CTRL_C0_RESET |
+ pl310_write4(sc, PL310_EVENT_COUNTER_CTRL,
+ EVENT_COUNTER_CTRL_ENABLED |
+ EVENT_COUNTER_CTRL_C0_RESET |
EVENT_COUNTER_CTRL_C1_RESET);
config_intrhook_disestablish(sc->sc_ich);
@@ -426,7 +426,7 @@ pl310_config_intr(void *arg)
static int
pl310_probe(device_t dev)
{
-
+
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
@@ -444,7 +444,7 @@ pl310_attach(device_t dev)
sc->sc_dev = dev;
rid = 0;
- sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (sc->sc_mem_res == NULL)
panic("%s: Cannot map registers", device_get_name(dev));
@@ -501,7 +501,7 @@ pl310_attach(device_t dev)
pl310_write4(pl310_softc, PL310_INV_WAY, 0xffff);
pl310_wait_background_op(PL310_INV_WAY, 0xffff);
platform_pl310_write_ctrl(sc, CTRL_ENABLED);
- device_printf(dev, "L2 Cache enabled: %uKB/%dB %d ways\n",
+ device_printf(dev, "L2 Cache enabled: %uKB/%dB %d ways\n",
(g_l2cache_size / 1024), g_l2cache_line_size, g_ways_assoc);
if (bootverbose)
pl310_print_config(sc);
diff --git a/sys/arm/arm/pmap-v6-new.c b/sys/arm/arm/pmap-v6-new.c
index 8fd6222faadd..13a97dea5186 100644
--- a/sys/arm/arm/pmap-v6-new.c
+++ b/sys/arm/arm/pmap-v6-new.c
@@ -2194,7 +2194,7 @@ pmap_release(pmap_t pmap)
pmap->pm_stats.resident_count));
KASSERT(pt2tab_user_is_empty(pmap->pm_pt2tab),
("%s: has allocated user PT2(s)", __func__));
- KASSERT(CPU_EMPTY(&pmap->pm_active),
+ KASSERT(CPU_EMPTY(&pmap->pm_active),
("%s: pmap %p is active on some CPU(s)", __func__, pmap));
mtx_lock_spin(&allpmaps_lock);
@@ -5768,6 +5768,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
~PTE1_W;
dst_pmap->pm_stats.resident_count +=
PTE1_SIZE / PAGE_SIZE;
+ pmap_pte1_mappings++;
}
continue;
} else if (!pte1_is_link(src_pte1))
@@ -5958,7 +5959,7 @@ pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa)
{
vm_offset_t sva;
- KASSERT((size & PAGE_MASK) == 0,
+ KASSERT((size & PAGE_MASK) == 0,
("%s: device mapping not page-sized", __func__));
sva = va;
@@ -5976,7 +5977,7 @@ pmap_kremove_device(vm_offset_t va, vm_size_t size)
{
vm_offset_t sva;
- KASSERT((size & PAGE_MASK) == 0,
+ KASSERT((size & PAGE_MASK) == 0,
("%s: device mapping not page-sized", __func__));
sva = va;
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index 0e0d884c3be5..a9421aa00e57 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -1145,7 +1145,7 @@ vector_page_setprot(int prot)
/*
* Set referenced flag.
* Vectors' page is always desired
- * to be allowed to reside in TLB.
+ * to be allowed to reside in TLB.
*/
*ptep |= L2_S_REF;
@@ -2221,7 +2221,7 @@ pmap_remove_pages(pmap_t pmap)
vm_offset_t va;
uint32_t inuse, bitmask;
int allfree, bit, field, idx;
-
+
rw_wlock(&pvh_global_lock);
PMAP_LOCK(pmap);
@@ -2455,7 +2455,7 @@ pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa)
{
vm_offset_t sva;
- KASSERT((size & PAGE_MASK) == 0,
+ KASSERT((size & PAGE_MASK) == 0,
("%s: device mapping not page-sized", __func__));
sva = va;
@@ -2472,7 +2472,7 @@ pmap_kremove_device(vm_offset_t va, vm_size_t size)
{
vm_offset_t sva;
- KASSERT((size & PAGE_MASK) == 0,
+ KASSERT((size & PAGE_MASK) == 0,
("%s: device mapping not page-sized", __func__));
sva = va;
@@ -3093,7 +3093,7 @@ do_l2b_alloc:
if ((pve = pmap_remove_pv(om, pmap, va))) {
is_exec |= PTE_BEEN_EXECD(opte);
is_refd |= PTE_BEEN_REFD(opte);
-
+
if (m && ((m->oflags & VPO_UNMANAGED)))
pmap_free_pv_entry(pmap, pve);
}
@@ -3303,7 +3303,7 @@ pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
vm_offset_t next_bucket;
vm_paddr_t pa;
vm_page_t m;
-
+
rw_wlock(&pvh_global_lock);
PMAP_LOCK(pmap);
while (sva < eva) {
@@ -3572,7 +3572,7 @@ pmap_pv_insert_section(pmap_t pmap, vm_offset_t va, vm_paddr_t pa)
pv_entry_t pv;
rw_assert(&pvh_global_lock, RA_WLOCKED);
- if (pv_entry_count < pv_entry_high_water &&
+ if (pv_entry_count < pv_entry_high_water &&
(pv = pmap_get_pv_entry(pmap, TRUE)) != NULL) {
pv->pv_va = va;
pvh = pa_to_pvh(pa);
@@ -3661,7 +3661,7 @@ pmap_pv_promote_section(pmap_t pmap, vm_offset_t va, vm_paddr_t pa)
* Tries to create a 1MB page mapping. Returns TRUE if successful and
* FALSE otherwise. Fails if (1) page is unmanageg, kernel pmap or vectors
* page, (2) a mapping already exists at the specified virtual address, or
- * (3) a pv entry cannot be allocated without reclaiming another pv entry.
+ * (3) a pv entry cannot be allocated without reclaiming another pv entry.
*/
static boolean_t
pmap_enter_section(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
@@ -3692,7 +3692,7 @@ pmap_enter_section(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
" in pmap %p", va, pmap);
return (FALSE);
}
- pa = VM_PAGE_TO_PHYS(m);
+ pa = VM_PAGE_TO_PHYS(m);
/*
* Abort this mapping if its PV entry could not be created.
*/
@@ -3767,7 +3767,7 @@ pmap_remove_section(pmap_t pmap, vm_offset_t sva)
TAILQ_EMPTY(&pvh->pv_list))
vm_page_aflag_clear(m, PGA_WRITEABLE);
}
-
+
l2b = pmap_get_l2_bucket(pmap, sva);
if (l2b != NULL) {
KASSERT(l2b->l2b_occupancy == L2_PTE_NUM_TOTAL,
@@ -3879,8 +3879,8 @@ pmap_promote_section(pmap_t pmap, vm_offset_t va)
if (!L2_S_EXECUTABLE(firstpte))
prot &= ~VM_PROT_EXECUTE;
- /*
- * Examine each of the other PTEs in the specified l2_bucket.
+ /*
+ * Examine each of the other PTEs in the specified l2_bucket.
* Abort if this PTE maps an unexpected 4KB physical page or
* does not have identical characteristics to the first PTE.
*/
@@ -4000,7 +4000,7 @@ pmap_demote_section(pmap_t pmap, vm_offset_t va)
/*
* According to assumptions described in pmap_promote_section,
* kernel is and always should be mapped using 1MB section mappings.
- * What more, managed kernel pages were not to be promoted.
+ * What more, managed kernel pages were not to be promoted.
*/
KASSERT(pmap != pmap_kernel() && L1_IDX(va) != L1_IDX(vector_page),
("pmap_demote_section: forbidden section mapping"));
@@ -4010,7 +4010,7 @@ pmap_demote_section(pmap_t pmap, vm_offset_t va)
l1pd = *pl1pd;
KASSERT((l1pd & L1_TYPE_MASK) == L1_S_PROTO,
("pmap_demote_section: not section or invalid section"));
-
+
pa = l1pd & L1_S_FRAME;
m = PHYS_TO_VM_PAGE(pa);
KASSERT((m != NULL && (m->oflags & VPO_UNMANAGED) == 0),
@@ -4063,7 +4063,7 @@ pmap_demote_section(pmap_t pmap, vm_offset_t va)
/*
* If the mapping has changed attributes, update the page table
* entries.
- */
+ */
if ((*firstptep & L2_S_PROMOTE) != (L1_S_DEMOTE(l1pd)))
pmap_fill_l2b(l2b, newpte);
}
@@ -4493,7 +4493,7 @@ pmap_zero_page_gen(vm_page_t m, int off, int size)
{
struct czpages *czp;
- KASSERT(TAILQ_EMPTY(&m->md.pv_list),
+ KASSERT(TAILQ_EMPTY(&m->md.pv_list),
("pmap_zero_page_gen: page has mappings"));
vm_paddr_t phys = VM_PAGE_TO_PHYS(m);
@@ -4501,7 +4501,7 @@ pmap_zero_page_gen(vm_page_t m, int off, int size)
sched_pin();
czp = &cpu_czpages[PCPU_GET(cpuid)];
mtx_lock(&czp->lock);
-
+
/*
* Hook in the page, zero it.
*/
@@ -4589,7 +4589,7 @@ pmap_copy_page_generic(vm_paddr_t src, vm_paddr_t dst)
sched_pin();
czp = &cpu_czpages[PCPU_GET(cpuid)];
mtx_lock(&czp->lock);
-
+
/*
* Map the pages into the page hook points, copy them, and purge the
* cache for the appropriate page.
@@ -5338,7 +5338,7 @@ pmap_dmap_iscurrent(pmap_t pmap)
void
pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
{
- /*
+ /*
* Remember the memattr in a field that gets used to set the appropriate
* bits in the PTEs as mappings are established.
*/
diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c
index 55e1aabf8c92..dfd5bcb39ef0 100644
--- a/sys/arm/arm/pmap.c
+++ b/sys/arm/arm/pmap.c
@@ -1005,7 +1005,7 @@ pmap_l2ptp_ctor(void *mem, int size, void *arg, int flags)
l2b = pmap_get_l2_bucket(pmap_kernel(), va);
ptep = &l2b->l2b_kva[l2pte_index(va)];
pte = *ptep;
-
+
if ((pte & L2_S_CACHE_MASK) != pte_l2_s_cache_mode_pt) {
/*
* Page tables must have the cache-mode set to
@@ -1357,7 +1357,7 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
if (!(oflags & maskbits)) {
if ((maskbits & PVF_WRITE) && (pv->pv_flags & PVF_NC)) {
- if (pg->md.pv_memattr !=
+ if (pg->md.pv_memattr !=
VM_MEMATTR_UNCACHEABLE) {
PMAP_LOCK(pm);
l2b = pmap_get_l2_bucket(pm, va);
@@ -1955,7 +1955,7 @@ pmap_postinit(void)
pt_entry_t *ptep, pte;
vm_offset_t va, eva;
u_int loop, needed;
-
+
needed = (maxproc / PMAP_DOMAINS) + ((maxproc % PMAP_DOMAINS) ? 1 : 0);
needed -= 1;
l1 = malloc(sizeof(*l1) * needed, M_VMPMAP, M_WAITOK);
@@ -1970,7 +1970,7 @@ pmap_postinit(void)
eva = va + L1_TABLE_SIZE;
pl1pt = (pd_entry_t *)va;
-
+
while (va < eva) {
l2b = pmap_get_l2_bucket(pmap_kernel(), va);
ptep = &l2b->l2b_kva[l2pte_index(va)];
@@ -1979,7 +1979,7 @@ pmap_postinit(void)
*ptep = pte;
PTE_SYNC(ptep);
cpu_tlb_flushD_SE(va);
-
+
va += PAGE_SIZE;
}
pmap_init_l1(l1, pl1pt);
@@ -2162,11 +2162,11 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt)
PDEBUG(1, printf("firstaddr = %08x, lastaddr = %08x\n",
firstaddr, vm_max_kernel_address));
-
+
virtual_avail = firstaddr;
kernel_pmap->pm_l1 = l1;
kernel_l1pa = l1pt->pv_pa;
-
+
/*
* Scan the L1 translation table created by initarm() and create
* the required metadata for all valid mappings found in it.
@@ -2187,7 +2187,7 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt)
*/
pa = (vm_paddr_t)(pde & L1_C_ADDR_MASK);
ptep = (pt_entry_t *)kernel_pt_lookup(pa);
-
+
if (ptep == NULL) {
panic("pmap_bootstrap: No L2 for va 0x%x, pa 0x%lx",
(u_int)l1idx << L1_S_SHIFT, (long unsigned int)pa);
@@ -2241,7 +2241,7 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt)
}
}
-
+
/*
* Ensure the primary (kernel) L1 has the correct cache mode for
* a page table. Bitch if it is not correctly set.
@@ -2267,7 +2267,7 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt)
* Initialize the global pv list lock.
*/
rw_init_flags(&pvh_global_lock, "pmap pv global", RW_RECURSE);
-
+
/*
* Reserve some special page table entries/VA space for temporary
* mapping of pages.
@@ -2281,7 +2281,7 @@ pmap_bootstrap(vm_offset_t firstaddr, struct pv_addr *l1pt)
pmap_alloc_specials(&virtual_avail,
round_page(size * L2_TABLE_SIZE_REAL) / PAGE_SIZE,
&pmap_kernel_l2ptp_kva, NULL);
-
+
size = (size + (L2_BUCKET_SIZE - 1)) / L2_BUCKET_SIZE;
pmap_alloc_specials(&virtual_avail,
round_page(size * sizeof(struct l2_dtable)) / PAGE_SIZE,
@@ -2319,7 +2319,7 @@ void
pmap_release(pmap_t pmap)
{
struct pcb *pcb;
-
+
pmap_idcache_wbinv_all(pmap);
cpu_l2cache_wbinv_all();
pmap_tlb_flushID(pmap);
@@ -2352,7 +2352,7 @@ pmap_release(pmap_t pmap)
}
pmap_free_l1(pmap);
-
+
dprintf("pmap_release()\n");
}
@@ -2368,7 +2368,7 @@ pmap_grow_map(vm_offset_t va, pt_entry_t cache_mode, vm_paddr_t *pap)
pt_entry_t *ptep;
vm_paddr_t pa;
struct vm_page *pg;
-
+
pg = vm_page_alloc(NULL, 0, VM_ALLOC_NOOBJ | VM_ALLOC_WIRED);
if (pg == NULL)
return (1);
@@ -2530,7 +2530,7 @@ pmap_remove_pages(pmap_t pmap)
struct l2_bucket *l2b = NULL;
vm_page_t m;
pt_entry_t *pt;
-
+
rw_wlock(&pvh_global_lock);
PMAP_LOCK(pmap);
cpu_idcache_wbinv_all();
@@ -2576,7 +2576,7 @@ pmap_kenter_supersection(vm_offset_t va, uint64_t pa, int flags)
pd_entry_t pd = L1_S_PROTO | L1_S_SUPERSEC | (pa & L1_SUP_FRAME) |
(((pa >> 32) & 0xf) << 20) | L1_S_PROT(PTE_KERNEL,
VM_PROT_READ|VM_PROT_WRITE) | L1_S_DOM(PMAP_DOMAIN_KERNEL);
- struct l1_ttable *l1;
+ struct l1_ttable *l1;
vm_offset_t va0, va_end;
KASSERT(((va | pa) & L1_SUP_OFFSET) == 0,
@@ -2685,7 +2685,7 @@ pmap_kenter_internal(vm_offset_t va, vm_offset_t pa, int flags)
rw_wlock(&pvh_global_lock);
if (!TAILQ_EMPTY(&m->md.pv_list) || m->md.pv_kva != 0) {
if ((pve = pmap_get_pv_entry()) == NULL)
- panic("pmap_kenter_internal: no pv entries");
+ panic("pmap_kenter_internal: no pv entries");
PMAP_LOCK(pmap_kernel());
pmap_enter_pv(m, pve, pmap_kernel(), va,
PVF_WRITE | PVF_UNMAN);
@@ -2716,7 +2716,7 @@ pmap_kenter_device(vm_offset_t va, vm_size_t size, vm_paddr_t pa)
{
vm_offset_t sva;
- KASSERT((size & PAGE_MASK) == 0,
+ KASSERT((size & PAGE_MASK) == 0,
("%s: device mapping not page-sized", __func__));
sva = va;
@@ -2733,7 +2733,7 @@ pmap_kremove_device(vm_offset_t va, vm_size_t size)
{
vm_offset_t sva;
- KASSERT((size & PAGE_MASK) == 0,
+ KASSERT((size & PAGE_MASK) == 0,
("%s: device mapping not page-sized", __func__));
sva = va;
@@ -2775,7 +2775,7 @@ pmap_kremove(vm_offset_t va)
struct pv_entry *pve;
vm_page_t m;
vm_offset_t pa;
-
+
l2b = pmap_get_l2_bucket(pmap_kernel(), va);
if (!l2b)
return;
@@ -3287,9 +3287,9 @@ do_l2b_alloc:
* so no need to re-do referenced emulation here.
*/
npte |= L2_S_PROTO;
-
+
nflags |= PVF_REF;
-
+
if (m && ((prot & VM_PROT_WRITE) != 0 ||
(m->md.pvh_attrs & PVF_MOD))) {
/*
@@ -3310,7 +3310,7 @@ do_l2b_alloc:
*/
npte |= L2_TYPE_INV;
}
-
+
if (prot & VM_PROT_WRITE) {
npte |= L2_S_PROT_W;
if (m != NULL &&
@@ -3326,7 +3326,7 @@ do_l2b_alloc:
oflags = pmap_modify_pv(m, pmap, va,
PVF_WRITE | PVF_EXEC | PVF_WIRED |
PVF_MOD | PVF_REF, nflags);
-
+
/*
* We may need to flush the cache if we're
* doing rw-ro...
@@ -3544,7 +3544,7 @@ pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
pv_entry_t pv;
vm_offset_t next_bucket;
vm_page_t m;
-
+
rw_wlock(&pvh_global_lock);
PMAP_LOCK(pmap);
while (sva < eva) {
@@ -3690,7 +3690,7 @@ retry:
m = PHYS_TO_VM_PAGE(pa);
vm_page_hold(m);
}
-
+
} else {
/*
* Note that we can't rely on the validity of the L1
@@ -3717,13 +3717,13 @@ retry:
case L2_TYPE_L:
pa = (pte & L2_L_FRAME) | (va & L2_L_OFFSET);
break;
-
+
default:
pa = (pte & L2_S_FRAME) | (va & L2_S_OFFSET);
break;
}
if (vm_page_pa_tryrelock(pmap, pa & PG_FRAME, &paddr))
- goto retry;
+ goto retry;
m = PHYS_TO_VM_PAGE(pa);
vm_page_hold(m);
}
@@ -3743,12 +3743,12 @@ int
pmap_pinit(pmap_t pmap)
{
PDEBUG(1, printf("pmap_pinit: pmap = %08x\n", (uint32_t) pmap));
-
+
pmap_alloc_l1(pmap);
bzero(pmap->pm_l2, sizeof(pmap->pm_l2));
CPU_ZERO(&pmap->pm_active);
-
+
TAILQ_INIT(&pmap->pm_pvlist);
bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
pmap->pm_stats.resident_count = 1;
@@ -3783,7 +3783,7 @@ static pv_entry_t
pmap_get_pv_entry(void)
{
pv_entry_t ret_value;
-
+
pv_entry_count++;
if (pv_entry_count > pv_entry_high_water)
pagedaemon_wakeup();
@@ -4353,7 +4353,7 @@ pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
pv_entry_t pv;
int loops = 0;
boolean_t rv;
-
+
KASSERT((m->oflags & VPO_UNMANAGED) == 0,
("pmap_page_exists_quick: page %p is not managed", m));
rv = FALSE;
@@ -4425,7 +4425,7 @@ pmap_is_modified(vm_page_t m)
("pmap_is_modified: page %p is not managed", m));
if (m->md.pvh_attrs & PVF_MOD)
return (TRUE);
-
+
return(FALSE);
}
@@ -4631,7 +4631,7 @@ pmap_link_l2pt(vm_offset_t l1pt, vm_offset_t va, struct pv_addr *l2pv)
SLIST_INSERT_HEAD(&kernel_pt_list, l2pv, pv_list);
-
+
}
/*
@@ -4793,7 +4793,7 @@ pmap_map_chunk(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa,
void
pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
{
- /*
+ /*
* Remember the memattr in a field that gets used to set the appropriate
* bits in the PTEs as mappings are established.
*/
diff --git a/sys/arm/arm/stack_machdep.c b/sys/arm/arm/stack_machdep.c
index 9c984a9b4ac8..9e68023e8d92 100644
--- a/sys/arm/arm/stack_machdep.c
+++ b/sys/arm/arm/stack_machdep.c
@@ -49,16 +49,6 @@ extern vm_offset_t kernel_vm_end;
static void
stack_capture(struct stack *st, u_int32_t *frame)
{
-#if !defined(__ARM_EABI__) && !defined(__clang__)
- vm_offset_t callpc;
-
- while (INKERNEL(frame) && (vm_offset_t)frame < kernel_vm_end) {
- callpc = frame[FR_SCP];
- if (stack_put(st, callpc) == -1)
- break;
- frame = (u_int32_t *)(frame[FR_RFP]);
- }
-#endif
}
void
diff --git a/sys/arm/arm/support.S b/sys/arm/arm/support.S
index b095aed33a4f..e26ac8214ff4 100644
--- a/sys/arm/arm/support.S
+++ b/sys/arm/arm/support.S
@@ -430,7 +430,7 @@ EENTRY(memmove)
/* blat 32 bytes at a time */
/* XXX for really big copies perhaps we should use more registers */
-.Lmemmove_floop32:
+.Lmemmove_floop32:
ldmia r1!, {r3, r4, r12, lr}
stmia r0!, {r3, r4, r12, lr}
ldmia r1!, {r3, r4, r12, lr}
@@ -988,7 +988,7 @@ ENTRY(memcpy)
/* blat 32 bytes at a time */
/* XXX for really big copies perhaps we should use more registers */
-.Lmemcpy_loop32:
+.Lmemcpy_loop32:
ldmia r1!, {r3, r4, r12, lr}
stmia r0!, {r3, r4, r12, lr}
ldmia r1!, {r3, r4, r12, lr}
diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S
index 477355706d7b..ee6368553bcc 100644
--- a/sys/arm/arm/swtch.S
+++ b/sys/arm/arm/swtch.S
@@ -143,7 +143,7 @@ ENTRY(cpu_throw)
GET_PCPU(r7, r9)
ldr r7, [r5, #(TD_PCB)] /* r7 = new thread's PCB */
-
+
/* Switch to lwp0 context */
ldr r9, .Lcpufuncs
@@ -198,20 +198,20 @@ ENTRY(cpu_throw)
str r7, [r6, #PC_CURPCB]
/* We have a new curthread now so make a note it */
str r5, [r6, #PC_CURTHREAD]
-#ifndef ARM_TP_ADDRESS
+#if __ARM_ARCH >= 6
mcr p15, 0, r5, c13, c0, 4
#endif
/* Set the new tp */
ldr r6, [r5, #(TD_MD + MD_TP)]
-#ifdef ARM_TP_ADDRESS
+#if __ARM_ARCH >= 6
+ mcr p15, 0, r6, c13, c0, 3
+#else
ldr r4, =ARM_TP_ADDRESS
str r6, [r4]
ldr r6, [r5, #(TD_MD + MD_RAS_START)]
str r6, [r4, #4] /* ARM_RAS_START */
ldr r6, [r5, #(TD_MD + MD_RAS_END)]
str r6, [r4, #8] /* ARM_RAS_END */
-#else
- mcr p15, 0, r6, c13, c0, 3
#endif
/* Restore all the saved registers and exit */
add r3, r7, #PCB_R4
@@ -245,7 +245,7 @@ ENTRY(cpu_switch)
/* We have a new curthread now so make a note it */
GET_PCPU(r7, r2)
str r1, [r7, #PC_CURTHREAD]
-#ifndef ARM_TP_ADDRESS
+#if __ARM_ARCH >= 6
mcr p15, 0, r1, c13, c0, 4
#endif
@@ -259,7 +259,14 @@ ENTRY(cpu_switch)
ldr r2, [r0, #(TD_PCB)]
mov r4, r0 /* Save the old thread. */
-#ifdef ARM_TP_ADDRESS
+#if __ARM_ARCH >= 6
+ /*
+ * Set new tp. No need to store the old one first, userland can't
+ * change it directly on armv6.
+ */
+ ldr r9, [r1, #(TD_MD + MD_TP)]
+ mcr p15, 0, r9, c13, c0, 3
+#else
/* Store the old tp; userland can change it on armv4. */
ldr r3, =ARM_TP_ADDRESS
ldr r9, [r3]
@@ -276,15 +283,8 @@ ENTRY(cpu_switch)
str r9, [r3, #4]
ldr r9, [r1, #(TD_MD + MD_RAS_END)]
str r9, [r3, #8]
-#else
- /*
- * Set new tp. No need to store the old one first, userland can't
- * change it directly on armv6.
- */
- ldr r9, [r1, #(TD_MD + MD_TP)]
- mcr p15, 0, r9, c13, c0, 3
#endif
-
+
/* Get the user structure for the new process in r9 */
ldr r9, [r1, #(TD_PCB)]
@@ -407,7 +407,7 @@ ENTRY(cpu_switch)
cmp r4, r6
beq 1b
#endif
-
+
/* XXXSCW: Safe to re-enable FIQs here */
/* rem: r9 = new PCB */
@@ -794,7 +794,7 @@ END(cpu_switch)
ENTRY(savectx)
stmfd sp!, {lr}
sub sp, sp, #4
-
+
/* Store all the registers in the thread's pcb */
add r3, r0, #(PCB_R4)
stmia r3, {r4-r12, sp, lr, pc}
diff --git a/sys/arm/arm/sys_machdep.c b/sys/arm/arm/sys_machdep.c
index b12cdd57e924..efebda32262e 100644
--- a/sys/arm/arm/sys_machdep.c
+++ b/sys/arm/arm/sys_machdep.c
@@ -41,8 +41,13 @@ __FBSDID("$FreeBSD$");
#include <sys/sysproto.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <machine/acle-compat.h>
+#include <machine/cpu-v6.h>
#include <machine/sysarch.h>
+#include <machine/vmparam.h>
#ifndef _SYS_SYSPROTO_H_
struct sysarch_args {
@@ -55,16 +60,89 @@ struct sysarch_args {
static int arm32_sync_icache (struct thread *, void *);
static int arm32_drain_writebuf(struct thread *, void *);
+#if __ARM_ARCH >= 6
+static int
+sync_icache(uintptr_t addr, size_t len)
+{
+ size_t size;
+ vm_offset_t rv;
+
+ /*
+ * Align starting address to even number because value of "1"
+ * is used as return value for success.
+ */
+ len += addr & 1;
+ addr &= ~1;
+
+ /* Break whole range to pages. */
+ do {
+ size = PAGE_SIZE - (addr & PAGE_MASK);
+ size = min(size, len);
+ rv = dcache_wb_pou_checked(addr, size);
+ if (rv == 1) /* see dcache_wb_pou_checked() */
+ rv = icache_inv_pou_checked(addr, size);
+ if (rv != 1) {
+ if (!useracc((void *)addr, size, VM_PROT_READ)) {
+ /* Invalid access */
+ return (rv);
+ }
+ /* Valid but unmapped page - skip it. */
+ }
+ len -= size;
+ addr += size;
+ } while (len > 0);
+
+ /* Invalidate branch predictor buffer. */
+ bpb_inv_all();
+ return (1);
+}
+#endif
+
static int
arm32_sync_icache(struct thread *td, void *args)
{
struct arm_sync_icache_args ua;
int error;
+ ksiginfo_t ksi;
+#if __ARM_ARCH >= 6
+ vm_offset_t rv;
+#endif
if ((error = copyin(args, &ua, sizeof(ua))) != 0)
return (error);
+ if (ua.len == 0) {
+ td->td_retval[0] = 0;
+ return (0);
+ }
+
+ /*
+ * Validate arguments. Address and length are unsigned,
+ * so we can use wrapped overflow check.
+ */
+ if (((ua.addr + ua.len) < ua.addr) ||
+ ((ua.addr + ua.len) > VM_MAXUSER_ADDRESS)) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGSEGV;
+ ksi.ksi_code = SEGV_ACCERR;
+ ksi.ksi_addr = (void *)max(ua.addr, VM_MAXUSER_ADDRESS);
+ trapsignal(td, &ksi);
+ return (EINVAL);
+ }
+
+#if __ARM_ARCH >= 6
+ rv = sync_icache(ua.addr, ua.len);
+ if (rv != 1) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGSEGV;
+ ksi.ksi_code = SEGV_MAPERR;
+ ksi.ksi_addr = (void *)rv;
+ trapsignal(td, &ksi);
+ return (EINVAL);
+ }
+#else
cpu_icache_sync_range(ua.addr, ua.len);
+#endif
td->td_retval[0] = 0;
return (0);
@@ -85,7 +163,7 @@ arm32_set_tp(struct thread *td, void *args)
{
td->td_md.md_tp = (register_t)args;
-#ifndef ARM_TP_ADDRESS
+#if __ARM_ARCH >= 6
set_tls(args);
#else
*(register_t *)ARM_TP_ADDRESS = (register_t)args;
@@ -97,7 +175,7 @@ static int
arm32_get_tp(struct thread *td, void *args)
{
-#ifndef ARM_TP_ADDRESS
+#if __ARM_ARCH >= 6
td->td_retval[0] = td->td_md.md_tp;
#else
td->td_retval[0] = *(register_t *)ARM_TP_ADDRESS;
diff --git a/sys/arm/arm/trap-v6.c b/sys/arm/arm/trap-v6.c
index abafa8619f45..b15062c05534 100644
--- a/sys/arm/arm/trap-v6.c
+++ b/sys/arm/arm/trap-v6.c
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#endif
extern char fusubailout[];
+extern char cachebailout[];
#ifdef DEBUG
int last_fault_code; /* For the benefit of pmap_fault_fixup() */
@@ -133,7 +134,7 @@ static const struct abort aborts[] = {
{abort_align, "Alignment Fault"},
{abort_fatal, "Debug Event"},
{NULL, "Access Bit (L1)"},
- {abort_icache, "Instruction cache maintenance"},
+ {NULL, "Instruction cache maintenance"},
{NULL, "Translation Fault (L1)"},
{NULL, "Access Bit (L2)"},
{NULL, "Translation Fault (L2)"},
@@ -394,8 +395,8 @@ abort_handler(struct trapframe *tf, int prefetch)
p = td->td_proc;
if (usermode) {
td->td_pticks = 0;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
}
/* Invoke the appropriate handler, if necessary. */
@@ -406,6 +407,24 @@ abort_handler(struct trapframe *tf, int prefetch)
}
/*
+ * Don't pass faulting cache operation to vm_fault(). We don't want
+ * to handle all vm stuff at this moment.
+ */
+ pcb = td->td_pcb;
+ if (__predict_false(pcb->pcb_onfault == cachebailout)) {
+ tf->tf_r0 = far; /* return failing address */
+ tf->tf_pc = (register_t)pcb->pcb_onfault;
+ return;
+ }
+
+ /* Handle remaining I cache aborts. */
+ if (idx == FAULT_ICACHE) {
+ if (abort_icache(tf, idx, fsr, far, prefetch, td, &ksig))
+ goto do_trapsignal;
+ goto out;
+ }
+
+ /*
* At this point, we're dealing with one of the following aborts:
*
* FAULT_TRAN_xx - Translation
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index 0f142ce06b5b..56407aa0348a 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -98,6 +98,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_map.h>
#include <vm/vm_extern.h>
+#include <machine/acle-compat.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/machdep.h>
@@ -119,7 +120,7 @@ struct ksig {
u_long code;
};
struct data_abort {
- int (*func)(struct trapframe *, u_int, u_int, struct thread *,
+ int (*func)(struct trapframe *, u_int, u_int, struct thread *,
struct ksig *);
const char *desc;
};
@@ -214,8 +215,8 @@ abort_handler(struct trapframe *tf, int type)
if (user) {
td->td_pticks = 0;
td->td_frame = tf;
- if (td->td_ucred != td->td_proc->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != td->td_proc->p_cowgen)
+ thread_cow_update(td);
}
/* Grab the current pcb */
@@ -325,7 +326,7 @@ abort_handler(struct trapframe *tf, int type)
* location, so we can deal with those quickly. Otherwise we need to
* disassemble the faulting instruction to determine if it was a write.
*/
-#if ARM_ARCH_6 || ARM_ARCH_7A
+#if __ARM_ARCH >= 6
ftype = (fsr & FAULT_WNR) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ;
#else
if (IS_PERMISSION_FAULT(fsr))
@@ -644,8 +645,8 @@ prefetch_abort_handler(struct trapframe *tf)
if (TRAP_USERMODE(tf)) {
td->td_frame = tf;
- if (td->td_ucred != td->td_proc->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != td->td_proc->p_cowgen)
+ thread_cow_update(td);
}
fault_pc = tf->tf_pc;
if (td->td_md.md_spinlock_count == 0) {
@@ -763,4 +764,4 @@ badaddr_read(void *addr, size_t size, void *rptr)
/* Return EFAULT if the address was invalid, else zero */
return (rv);
-} \ No newline at end of file
+}
diff --git a/sys/arm/arm/vfp.c b/sys/arm/arm/vfp.c
index 38aff98ad1cc..2494461c1158 100644
--- a/sys/arm/arm/vfp.c
+++ b/sys/arm/arm/vfp.c
@@ -107,7 +107,7 @@ vfp_init(void)
coproc = get_coprocessorACR();
coproc |= COPROC10 | COPROC11;
set_coprocessorACR(coproc);
-
+
fpsid = fmrx(fpsid); /* read the vfp system id */
fpexc = fmrx(fpexc); /* read the vfp exception reg */
@@ -199,7 +199,7 @@ vfp_bounce(u_int addr, u_int insn, struct trapframe *frame, int code)
*/
fmxr(fpexc, fpexc | VFPEXC_EN);
curpcb = curthread->td_pcb;
- cpu = PCPU_GET(cpu);
+ cpu = PCPU_GET(cpuid);
if (curpcb->pcb_vfpcpu != cpu || curthread != PCPU_GET(fpcurthread)) {
vfp_restore(&curpcb->pcb_vfpstate);
curpcb->pcb_vfpcpu = cpu;
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 5e4ee0c50dd0..223ad96cfb39 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -54,6 +54,8 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/unistd.h>
+
+#include <machine/acle-compat.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/pcb.h>
@@ -108,10 +110,10 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
#endif
#endif
td2->td_pcb = pcb2;
-
+
/* Clone td1's pcb */
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
-
+
/* Point to mdproc and then copy over td1's contents */
mdp2 = &p2->p_md;
bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
@@ -133,7 +135,7 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
pcb2->pcb_vfpcpu = -1;
pcb2->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ;
-
+
tf = td2->td_frame;
tf->tf_spsr &= ~PSR_C;
tf->tf_r0 = 0;
@@ -143,13 +145,13 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
/* Setup to release spin count in fork_exit(). */
td2->td_md.md_spinlock_count = 1;
td2->td_md.md_saved_cspr = PSR_SVC32_MODE;;
-#ifdef ARM_TP_ADDRESS
- td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS;
-#else
+#if __ARM_ARCH >= 6
td2->td_md.md_tp = td1->td_md.md_tp;
+#else
+ td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS;
#endif
}
-
+
void
cpu_thread_swapin(struct thread *td)
{
@@ -273,10 +275,10 @@ cpu_set_user_tls(struct thread *td, void *tls_base)
td->td_md.md_tp = (register_t)tls_base;
if (td == curthread) {
critical_enter();
-#ifdef ARM_TP_ADDRESS
- *(register_t *)ARM_TP_ADDRESS = (register_t)tls_base;
-#else
+#if __ARM_ARCH >= 6
set_tls(tls_base);
+#else
+ *(register_t *)ARM_TP_ADDRESS = (register_t)tls_base;
#endif
critical_exit();
}
@@ -336,7 +338,7 @@ cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
void
swi_vm(void *dummy)
{
-
+
if (busdma_swi_pending)
busdma_swi();
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
index e950ec6913b3..33204badd0bf 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c
@@ -76,23 +76,13 @@ TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode);
struct bcm_sdhci_softc {
device_t sc_dev;
- struct mtx sc_mtx;
struct resource * sc_mem_res;
struct resource * sc_irq_res;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
void * sc_intrhand;
struct mmc_request * sc_req;
- struct mmc_data * sc_data;
- uint32_t sc_flags;
-#define LPC_SD_FLAGS_IGNORECRC (1 << 0)
- int sc_xfer_direction;
-#define DIRECTION_READ 0
-#define DIRECTION_WRITE 1
- int sc_xfer_done;
- int sc_bus_busy;
struct sdhci_slot sc_slot;
- int sc_dma_inuse;
int sc_dma_ch;
bus_dma_tag_t sc_dma_tag;
bus_dmamap_t sc_dma_map;
@@ -113,11 +103,6 @@ static void bcm_sdhci_intr(void *);
static int bcm_sdhci_get_ro(device_t, device_t);
static void bcm_sdhci_dma_intr(int ch, void *arg);
-#define bcm_sdhci_lock(_sc) \
- mtx_lock(&_sc->sc_mtx);
-#define bcm_sdhci_unlock(_sc) \
- mtx_unlock(&_sc->sc_mtx);
-
static void
bcm_sdhci_dmacb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
{
@@ -187,8 +172,6 @@ bcm_sdhci_attach(device_t dev)
if (bootverbose)
device_printf(dev, "SDHCI frequency: %dMHz\n", default_freq);
- mtx_init(&sc->sc_mtx, "bcm sdhci", "sdhci", MTX_DEF);
-
rid = 0;
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
@@ -277,7 +260,6 @@ fail:
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
- mtx_destroy(&sc->sc_mtx);
return (err);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_spi.c b/sys/arm/broadcom/bcm2835/bcm2835_spi.c
index 3692c6770cec..99de5e7d6c38 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_spi.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_spi.c
@@ -427,6 +427,15 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
("TX/RX data sizes should be equal"));
+ /* Get the proper chip select for this child. */
+ spibus_get_cs(child, &cs);
+ if (cs < 0 || cs > 2) {
+ device_printf(dev,
+ "Invalid chip select %d requested by %s\n", cs,
+ device_get_nameunit(child));
+ return (EINVAL);
+ }
+
BCM_SPI_LOCK(sc);
/* If the controller is in use wait until it is available. */
@@ -441,16 +450,6 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO,
SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO);
- /* Get the proper chip select for this child. */
- spibus_get_cs(child, &cs);
- if (cs < 0 || cs > 2) {
- device_printf(dev,
- "Invalid chip select %d requested by %s\n", cs,
- device_get_nameunit(child));
- BCM_SPI_UNLOCK(sc);
- return (EINVAL);
- }
-
/* Save a pointer to the SPI command. */
sc->sc_cmd = cmd;
sc->sc_read = 0;
@@ -471,8 +470,10 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
/* Make sure the SPI engine and interrupts are disabled. */
bcm_spi_modifyreg(sc, SPI_CS, SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 0);
- /* Clear the controller flags. */
+ /* Release the controller and wakeup the next thread waiting for it. */
sc->sc_flags = 0;
+ wakeup_one(dev);
+ BCM_SPI_UNLOCK(sc);
/*
* Check for transfer timeout. The SPI controller doesn't
@@ -483,8 +484,6 @@ bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
err = EIO;
}
- BCM_SPI_UNLOCK(sc);
-
return (err);
}
diff --git a/sys/arm/conf/ALPINE b/sys/arm/conf/ALPINE
index 626dcfa21d46..075cc1ff16a2 100644
--- a/sys/arm/conf/ALPINE
+++ b/sys/arm/conf/ALPINE
@@ -31,7 +31,7 @@ options SMP # Enable multiple cores
# Debugging
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
options KDB
options DDB #Enable the kernel debugger
diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE
index 6b8ab646d213..38c6b4a6b9a9 100644
--- a/sys/arm/conf/BEAGLEBONE
+++ b/sys/arm/conf/BEAGLEBONE
@@ -40,7 +40,7 @@ options PLATFORM
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/CUBIEBOARD b/sys/arm/conf/CUBIEBOARD
index 04c15027c1a5..c1df03aa1f09 100644
--- a/sys/arm/conf/CUBIEBOARD
+++ b/sys/arm/conf/CUBIEBOARD
@@ -29,7 +29,7 @@ options SCHED_4BSD # 4BSD scheduler
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/CUBIEBOARD2 b/sys/arm/conf/CUBIEBOARD2
index 86dbb2e07c4c..c8fded08a4d8 100644
--- a/sys/arm/conf/CUBIEBOARD2
+++ b/sys/arm/conf/CUBIEBOARD2
@@ -30,7 +30,7 @@ options SMP # Enable multiple cores
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR
index 16eeef911693..b00b3bf29825 100644
--- a/sys/arm/conf/DOCKSTAR
+++ b/sys/arm/conf/DOCKSTAR
@@ -50,7 +50,6 @@ options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
options ALT_BREAK_TO_DEBUGGER
options KDB # Enable kernel debugger support
options DDB # Enable the kernel debugger
diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001
index 247eadbef308..3baacaaaff4d 100644
--- a/sys/arm/conf/DREAMPLUG-1001
+++ b/sys/arm/conf/DREAMPLUG-1001
@@ -53,7 +53,6 @@ options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
options ALT_BREAK_TO_DEBUGGER
options KDB # Enable kernel debugger support
options DDB # Enable the kernel debugger
diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX
index dc22943ffc3a..2c4d973598e1 100644
--- a/sys/arm/conf/EFIKA_MX
+++ b/sys/arm/conf/EFIKA_MX
@@ -38,7 +38,7 @@ options INCLUDE_CONFIG_FILE # Include this file in kernel
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common
index 446d272e369d..80c8677dafdf 100644
--- a/sys/arm/conf/EXYNOS5.common
+++ b/sys/arm/conf/EXYNOS5.common
@@ -58,7 +58,7 @@ options SMP # Enable multiple cores
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/NOTES b/sys/arm/conf/NOTES
index 85a4c16b903a..885bfd17b042 100644
--- a/sys/arm/conf/NOTES
+++ b/sys/arm/conf/NOTES
@@ -86,3 +86,26 @@ nodevice cxgbe
nodevice pcii
nodevice snd_cmi
nodevice tnt4882
+
+#
+# Enable the kernel DTrace hooks which are required to load the DTrace
+# kernel modules.
+#
+options KDTRACE_HOOKS
+
+# DTrace core
+# NOTE: introduces CDDL-licensed components into the kernel
+#device dtrace
+
+# DTrace modules
+#device dtrace_lockstat
+#device dtrace_profile
+#device dtrace_sdt
+#device dtrace_fbt
+#device dtrace_systrace
+#device dtrace_prototype
+#device dtnfscl
+#device dtmalloc
+
+# Alternatively include all the DTrace modules
+#device dtraceall
diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD
index 0e1dec0021c3..d04b81a637fa 100644
--- a/sys/arm/conf/PANDABOARD
+++ b/sys/arm/conf/PANDABOARD
@@ -37,7 +37,7 @@ options SMP # Enable multiple cores
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188
index 540b49e6fe6f..1c9d0addce09 100644
--- a/sys/arm/conf/RK3188
+++ b/sys/arm/conf/RK3188
@@ -29,7 +29,7 @@ options SMP # Enable multiple cores
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B
index 9193bcae037f..db5f7678055a 100644
--- a/sys/arm/conf/RPI-B
+++ b/sys/arm/conf/RPI-B
@@ -30,7 +30,6 @@ options PLATFORM
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
diff --git a/sys/arm/conf/RPI2 b/sys/arm/conf/RPI2
index 27caac997d09..2e5b0549380c 100644
--- a/sys/arm/conf/RPI2
+++ b/sys/arm/conf/RPI2
@@ -31,7 +31,6 @@ options PLATFORM
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
diff --git a/sys/arm/conf/SOCKIT.common b/sys/arm/conf/SOCKIT.common
index 8c6e4750dd6c..f30dca19089b 100644
--- a/sys/arm/conf/SOCKIT.common
+++ b/sys/arm/conf/SOCKIT.common
@@ -31,7 +31,7 @@ options SMP # Enable multiple cores
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/VIRT b/sys/arm/conf/VIRT
index 3206fda4a2a8..bbaa5d7f745a 100644
--- a/sys/arm/conf/VIRT
+++ b/sys/arm/conf/VIRT
@@ -24,8 +24,9 @@ include "std.armv6"
include "../qemu/std.virt"
options HZ=100
-options SCHED_4BSD # 4BSD scheduler
+options SCHED_ULE # 4BSD scheduler
options PLATFORM
+options SMP # Enable multiple cores
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
@@ -66,3 +67,6 @@ device random # Entropy device
# Flattened Device Tree
options FDT # Configure using FDT/DTB data
+# Extensible Firmware Interface
+options EFI
+
diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID
index a31ef07a7391..ed04653b4b65 100644
--- a/sys/arm/conf/VYBRID
+++ b/sys/arm/conf/VYBRID
@@ -31,7 +31,7 @@ options SCHED_4BSD # 4BSD scheduler
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
diff --git a/sys/arm/conf/YYHD18 b/sys/arm/conf/YYHD18
new file mode 100644
index 000000000000..1a251ce9e988
--- /dev/null
+++ b/sys/arm/conf/YYHD18
@@ -0,0 +1,26 @@
+# YYHD18 -- Custom configuration for the Yiyate Android TV box
+#
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
+#
+# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $FreeBSD$
+
+#NO_UNIVERSE
+
+include "AML8726"
+ident YYHD18
+
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=yyhd18-m3.dts
diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD
index a0fe66a58719..f5fc850759f9 100644
--- a/sys/arm/conf/ZEDBOARD
+++ b/sys/arm/conf/ZEDBOARD
@@ -30,7 +30,7 @@ options SMP # Enable multiple cores
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-#options BREAK_TO_DEBUGGER
+options ALT_BREAK_TO_DEBUGGER
options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
#options KDB_TRACE # Print a stack trace for a panic
diff --git a/sys/arm/freescale/imx/imx6_sdma.c b/sys/arm/freescale/imx/imx6_sdma.c
index 91d66afc12eb..ae9a3390cc50 100644
--- a/sys/arm/freescale/imx/imx6_sdma.c
+++ b/sys/arm/freescale/imx/imx6_sdma.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
+#include <vm/pmap.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
diff --git a/sys/arm/include/_types.h b/sys/arm/include/_types.h
index e36699c553db..b6279631c9e7 100644
--- a/sys/arm/include/_types.h
+++ b/sys/arm/include/_types.h
@@ -105,15 +105,9 @@ typedef __uint32_t __vm_paddr_t;
typedef __uint64_t __vm_pindex_t;
typedef __uint32_t __vm_size_t;
-#ifdef __ARM_EABI__
typedef unsigned int ___wchar_t;
#define __WCHAR_MIN 0 /* min value for a wchar_t */
#define __WCHAR_MAX __UINT_MAX /* max value for a wchar_t */
-#else
-typedef int ___wchar_t;
-#define __WCHAR_MIN __INT_MIN /* min value for a wchar_t */
-#define __WCHAR_MAX __INT_MAX /* max value for a wchar_t */
-#endif
/*
* Unusual type definitions.
diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h
index 0c25d7bdc1ab..2f64c3758305 100644
--- a/sys/arm/include/asm.h
+++ b/sys/arm/include/asm.h
@@ -49,7 +49,7 @@
# define _ALIGN_TEXT .align 2
#endif
-#if defined(__ARM_EABI__) && !defined(_STANDALONE)
+#ifndef _STANDALONE
#define STOP_UNWINDING .cantunwind
#define _FNSTART .fnstart
#define _FNEND .fnend
diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h
index 348151322f1f..e4a893668cbc 100644
--- a/sys/arm/include/cpu-v6.h
+++ b/sys/arm/include/cpu-v6.h
@@ -139,6 +139,8 @@ _WF1(_CP15_ICIMVAU, CP15_ICIMVAU(%0)) /* Instruction cache invalidate */
/* Various control registers */
+_RF0(cp15_cpacr_get, CP15_CPACR(%0))
+_WF1(cp15_cpacr_set, CP15_CPACR(%0))
_RF0(cp15_dfsr_get, CP15_DFSR(%0))
_RF0(cp15_ifsr_get, CP15_IFSR(%0))
_WF1(cp15_prrr_set, CP15_PRRR(%0))
@@ -149,8 +151,10 @@ _RF0(cp15_dfar_get, CP15_DFAR(%0))
_RF0(cp15_ifar_get, CP15_IFAR(%0))
_RF0(cp15_l2ctlr_get, CP15_L2CTLR(%0))
#endif
-#if __ARM_ARCH >= 6
+/* ARMv6+ and XScale */
_RF0(cp15_actlr_get, CP15_ACTLR(%0))
+_WF1(cp15_actlr_set, CP15_ACTLR(%0))
+#if __ARM_ARCH >= 6
_WF1(cp15_ats1cpr_set, CP15_ATS1CPR(%0));
_RF0(cp15_par_get, CP15_PAR);
_RF0(cp15_sctlr_get, CP15_SCTLR(%0))
@@ -163,7 +167,10 @@ _RF0(cp15_tcmtr_get, CP15_TCMTR(%0))
_RF0(cp15_tlbtr_get, CP15_TLBTR(%0))
_RF0(cp15_mpidr_get, CP15_MPIDR(%0))
_RF0(cp15_revidr_get, CP15_REVIDR(%0))
+_RF0(cp15_ccsidr_get, CP15_CCSIDR(%0))
+_RF0(cp15_clidr_get, CP15_CLIDR(%0))
_RF0(cp15_aidr_get, CP15_AIDR(%0))
+_WF1(cp15_csselr_set, CP15_CSSELR(%0))
_RF0(cp15_id_pfr0_get, CP15_ID_PFR0(%0))
_RF0(cp15_id_pfr1_get, CP15_ID_PFR1(%0))
_RF0(cp15_id_dfr0_get, CP15_ID_DFR0(%0))
@@ -183,6 +190,10 @@ _RF0(cp15_cbar_get, CP15_CBAR(%0))
/* Performance Monitor registers */
#if __ARM_ARCH == 6 && defined(CPU_ARM1176)
+_RF0(cp15_pmuserenr_get, CP15_PMUSERENR(%0))
+_WF1(cp15_pmuserenr_set, CP15_PMUSERENR(%0))
+_RF0(cp15_pmcr_get, CP15_PMCR(%0))
+_WF1(cp15_pmcr_set, CP15_PMCR(%0))
_RF0(cp15_pmccntr_get, CP15_PMCCNTR(%0))
_WF1(cp15_pmccntr_set, CP15_PMCCNTR(%0))
#elif __ARM_ARCH > 6
diff --git a/sys/arm/include/pcpu.h b/sys/arm/include/pcpu.h
index ee79343af01a..73400c59fefa 100644
--- a/sys/arm/include/pcpu.h
+++ b/sys/arm/include/pcpu.h
@@ -32,6 +32,7 @@
#ifdef _KERNEL
+#include <machine/acle-compat.h>
#include <machine/cpuconf.h>
#define ALT_STACK_SIZE 128
@@ -40,14 +41,13 @@ struct vmspace;
#endif /* _KERNEL */
-#ifdef VFP
+#if __ARM_ARCH >= 6
#define PCPU_MD_FIELDS \
- unsigned int pc_cpu; \
unsigned int pc_vfpsid; \
unsigned int pc_vfpmvfr0; \
unsigned int pc_vfpmvfr1; \
struct pmap *pc_curpmap; \
- char __pad[137]
+ char __pad[141]
#else
#define PCPU_MD_FIELDS \
char __pad[157]
@@ -59,9 +59,8 @@ struct pcb;
struct pcpu;
extern struct pcpu *pcpup;
-#if ARM_ARCH_6 || ARM_ARCH_7A
-/* or ARM_TP_ADDRESS mark REMOVE ME NOTE */
+#if __ARM_ARCH >= 6
#define CPU_MASK (0xf)
#ifndef SMP
diff --git a/sys/arm/include/proc.h b/sys/arm/include/proc.h
index a86df3557ccc..25f44806802d 100644
--- a/sys/arm/include/proc.h
+++ b/sys/arm/include/proc.h
@@ -61,11 +61,7 @@ struct mdproc {
void *md_sigtramp;
};
-#ifdef __ARM_EABI__
#define KINFO_PROC_SIZE 816
-#else
-#define KINFO_PROC_SIZE 792
-#endif
#define MAXARGS 8
/*
diff --git a/sys/arm/include/sysreg.h b/sys/arm/include/sysreg.h
index fb1348736ece..31097e9a1650 100644
--- a/sys/arm/include/sysreg.h
+++ b/sys/arm/include/sysreg.h
@@ -210,6 +210,8 @@
* CP15 C9 registers
*/
#if __ARM_ARCH == 6 && defined(CPU_ARM1176)
+#define CP15_PMUSERENR(rr) p15, 0, rr, c15, c9, 0 /* Access Validation Control Register */
+#define CP15_PMCR(rr) p15, 0, rr, c15, c12, 0 /* Performance Monitor Control Register */
#define CP15_PMCCNTR(rr) p15, 0, rr, c15, c12, 1 /* PM Cycle Count Register */
#elif __ARM_ARCH > 6
#define CP15_L2CTLR(rr) p15, 1, rr, c9, c0, 2 /* L2 Control Register */
diff --git a/sys/arm/include/vmparam.h b/sys/arm/include/vmparam.h
index 91b6a63dd476..b6e76bf35758 100644
--- a/sys/arm/include/vmparam.h
+++ b/sys/arm/include/vmparam.h
@@ -84,13 +84,12 @@
#define VM_PHYSSEG_SPARSE
/*
- * Create two free page pools. Since the ARM kernel virtual address
+ * Create one free page pool. Since the ARM kernel virtual address
* space does not include a mapping onto the machine's entire physical
* memory, VM_FREEPOOL_DIRECT is defined as an alias for the default
* pool, VM_FREEPOOL_DEFAULT.
*/
-#define VM_NFREEPOOL 2
-#define VM_FREEPOOL_CACHE 1
+#define VM_NFREEPOOL 1
#define VM_FREEPOOL_DEFAULT 0
#define VM_FREEPOOL_DIRECT 0
diff --git a/sys/arm/qemu/files.qemu b/sys/arm/qemu/files.qemu
index 888c4c7acd26..48d7e4a8614f 100644
--- a/sys/arm/qemu/files.qemu
+++ b/sys/arm/qemu/files.qemu
@@ -13,3 +13,6 @@ kern/kern_clocksource.c standard
arm/arm/generic_timer.c standard
arm/qemu/virt_common.c standard
arm/qemu/virt_machdep.c standard
+arm/qemu/virt_mp.c optional smp
+
+dev/ofw/ofw_cpu.c standard
diff --git a/sys/arm/qemu/virt_mp.c b/sys/arm/qemu/virt_mp.c
new file mode 100644
index 000000000000..4942745e109f
--- /dev/null
+++ b/sys/arm/qemu/virt_mp.c
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 2015 Andrew Turner
+ * 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.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/pcpu.h>
+#include <sys/smp.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <machine/intr.h>
+#include <machine/smp.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_cpu.h>
+#include <dev/psci/psci.h>
+
+static int running_cpus;
+
+int
+platform_mp_probe(void)
+{
+ int ncpus;
+
+ ncpus = ofw_cpu_early_foreach(NULL, true);
+ if (ncpus <= 1) {
+ mp_ncpus = 1;
+ return (0);
+ }
+
+ mp_ncpus = MIN(ncpus, MAXCPU);
+
+ return (1);
+}
+
+static boolean_t
+virt_maxid(u_int id, phandle_t node, u_int addr_cells, pcell_t *reg)
+{
+
+ if (mp_maxid < id)
+ mp_maxid = id;
+
+ return (true);
+}
+
+void
+platform_mp_setmaxid(void)
+{
+
+ mp_maxid = PCPU_GET(cpuid);
+ ofw_cpu_early_foreach(virt_maxid, true);
+}
+
+static boolean_t
+virt_start_ap(u_int id, phandle_t node, u_int addr_cells, pcell_t *reg)
+{
+ int err;
+
+ if (running_cpus >= mp_ncpus)
+ return (false);
+ running_cpus++;
+
+ err = psci_cpu_on(*reg, pmap_kextract((vm_offset_t)mpentry), id);
+
+ if (err != PSCI_RETVAL_SUCCESS)
+ return (false);
+
+ return (true);
+}
+
+void
+platform_mp_start_ap(void)
+{
+
+ ofw_cpu_early_foreach(virt_start_ap, true);
+}
+
+void
+platform_mp_init_secondary(void)
+{
+
+ arm_init_secondary_ic();
+}
+
+void
+platform_ipi_send(cpuset_t cpus, u_int ipi)
+{
+
+ pic_ipi_send(cpus, ipi);
+}
diff --git a/sys/arm/ti/am335x/am335x_lcd.c b/sys/arm/ti/am335x/am335x_lcd.c
index df5c537544a5..501042a9fcd2 100644
--- a/sys/arm/ti/am335x/am335x_lcd.c
+++ b/sys/arm/ti/am335x/am335x_lcd.c
@@ -273,7 +273,7 @@ am335x_read_timing(device_t dev, phandle_t node, struct panel_info *panel)
int error;
phandle_t timings_node, timing_node, native;
- timings_node = fdt_find_child(node, "display-timings");
+ timings_node = ofw_bus_find_child(node, "display-timings");
if (timings_node == 0) {
device_printf(dev, "no \"display-timings\" node\n");
return (-1);
@@ -346,7 +346,7 @@ am335x_read_panel_info(device_t dev, phandle_t node, struct panel_info *panel)
int error;
phandle_t panel_info_node;
- panel_info_node = fdt_find_child(node, "panel-info");
+ panel_info_node = ofw_bus_find_child(node, "panel-info");
if (panel_info_node == 0)
return (-1);
diff --git a/sys/arm/ti/am335x/am335x_pmic.c b/sys/arm/ti/am335x/am335x_pmic.c
index 18bc438a9141..eefece8d0f6e 100644
--- a/sys/arm/ti/am335x/am335x_pmic.c
+++ b/sys/arm/ti/am335x/am335x_pmic.c
@@ -27,7 +27,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
-* TPS65217 PMIC companion chip for AM335x SoC sitting on I2C bus
+* TI TPS65217 PMIC companion chip for AM335x SoC sitting on I2C bus
*/
#include <sys/param.h>
#include <sys/systm.h>
@@ -50,30 +50,10 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/am335x/am335x_rtcvar.h>
+#include <arm/ti/am335x/tps65217x.h>
#include "iicbus_if.h"
-#define TPS65217A 0x7
-#define TPS65217B 0xF
-#define TPS65217C 0xE
-#define TPS65217D 0x6
-
-/* TPS65217 Reisters */
-#define TPS65217_CHIPID_REG 0x00
-#define TPS65217_INT_REG 0x02
-#define TPS65217_INT_PBM (1U << 6)
-#define TPS65217_INT_ACM (1U << 5)
-#define TPS65217_INT_USBM (1U << 4)
-#define TPS65217_INT_PBI (1U << 2)
-#define TPS65217_INT_ACI (1U << 1)
-#define TPS65217_INT_USBI (1U << 0)
-
-#define TPS65217_STATUS_REG 0x0A
-#define TPS65217_STATUS_OFF (1U << 7)
-#define TPS65217_STATUS_ACPWR (1U << 3)
-#define TPS65217_STATUS_USBPWR (1U << 2)
-#define TPS65217_STATUS_BT (1U << 0)
-
#define MAX_IIC_DATA_SIZE 2
@@ -85,6 +65,13 @@ struct am335x_pmic_softc {
void *sc_intrhand;
};
+static const char *tps65217_voreg_c[4] = {"4.10V", "4.15V", "4.20V", "4.25V"};
+
+static int am335x_pmic_bootverbose = 0;
+TUNABLE_INT("hw.am335x_pmic.bootverbose", &am335x_pmic_bootverbose);
+static char am335x_pmic_vo[6];
+TUNABLE_STR("hw.am335x_pmic.vo", am335x_pmic_vo, sizeof(am335x_pmic_vo));
+
static void am335x_pmic_shutdown(void *, int);
static int
@@ -120,18 +107,19 @@ static void
am335x_pmic_intr(void *arg)
{
struct am335x_pmic_softc *sc = (struct am335x_pmic_softc *)arg;
- uint8_t int_reg, status_reg;
+ struct tps65217_status_reg status_reg;
+ struct tps65217_int_reg int_reg;
int rv;
char notify_buf[16];
THREAD_SLEEPING_OK();
- rv = am335x_pmic_read(sc->sc_dev, TPS65217_INT_REG, &int_reg, 1);
+ rv = am335x_pmic_read(sc->sc_dev, TPS65217_INT_REG, (uint8_t *)&int_reg, 1);
if (rv != 0) {
device_printf(sc->sc_dev, "Cannot read interrupt register\n");
THREAD_NO_SLEEPING();
return;
}
- rv = am335x_pmic_read(sc->sc_dev, TPS65217_STATUS_REG, &status_reg, 1);
+ rv = am335x_pmic_read(sc->sc_dev, TPS65217_STATUS_REG, (uint8_t *)&status_reg, 1);
if (rv != 0) {
device_printf(sc->sc_dev, "Cannot read status register\n");
THREAD_NO_SLEEPING();
@@ -139,11 +127,11 @@ am335x_pmic_intr(void *arg)
}
THREAD_NO_SLEEPING();
- if ((int_reg & TPS65217_INT_PBI) && (status_reg & TPS65217_STATUS_BT))
+ if (int_reg.pbi && status_reg.pb)
shutdown_nice(RB_POWEROFF);
- if (int_reg & TPS65217_INT_ACI) {
+ if (int_reg.aci) {
snprintf(notify_buf, sizeof(notify_buf), "notify=0x%02x",
- (status_reg & TPS65217_STATUS_ACPWR) ? 1 : 0);
+ status_reg.acpwr);
devctl_notify_f("ACPI", "ACAD", "power", notify_buf, M_NOWAIT);
}
}
@@ -167,37 +155,120 @@ am335x_pmic_probe(device_t dev)
}
static void
+am335x_pmic_dump_chgconfig(device_t dev)
+{
+ struct tps65217_chgconfig0_reg reg0;
+ struct tps65217_chgconfig1_reg reg1;
+ struct tps65217_chgconfig2_reg reg2;
+ struct tps65217_chgconfig3_reg reg3;
+ const char *e_d[] = {"enabled", "disabled"};
+ const char *d_e[] = {"disabled", "enabled"};
+ const char *i_a[] = {"inactive", "active"};
+ const char *f_t[] = {"false", "true"};
+ const char *timer_c[] = {"4h", "5h", "6h", "8h"};
+ const char *ntc_type_c[] = {"100k", "10k"};
+ const char *vprechg_c[] = {"2.9V", "2.5V"};
+ const char *trange_c[] = {"0-45 C", "0-60 C"};
+ const char *termif_c[] = {"2.5%", "7.5%", "15%", "18%"};
+ const char *pchrgt_c[] = {"30 min", "60 min"};
+ const char *dppmth_c[] = {"3.50V", "3.75V", "4.00V", "4.25V"};
+ const char *ichrg_c[] = {"300mA", "400mA", "500mA", "700mA"};
+
+ am335x_pmic_read(dev, TPS65217_CHGCONFIG0_REG, (uint8_t *)&reg0, 1);
+ device_printf(dev, " BAT TEMP/NTC ERROR: %s\n", f_t[reg0.battemp]);
+ device_printf(dev, " Pre-charge timer time-out: %s\n", f_t[reg0.pchgtout]);
+ device_printf(dev, " Charge timer time-out: %s\n", f_t[reg0.chgtout]);
+ device_printf(dev, " Charger active: %s\n", f_t[reg0.active]);
+ device_printf(dev, " Termination current detected: %s\n", f_t[reg0.termi]);
+ device_printf(dev, " Thermal suspend: %s\n", f_t[reg0.tsusp]);
+ device_printf(dev, " DPPM active: %s\n", f_t[reg0.dppm]);
+ device_printf(dev, " Thermal regulation: %s\n", i_a[reg0.treg]);
+
+ am335x_pmic_read(dev, TPS65217_CHGCONFIG1_REG, (uint8_t *)&reg1, 1);
+ device_printf(dev, " Charger: %s\n", d_e[reg1.chg_en]);
+ device_printf(dev, " Suspend charge: %s\n", i_a[reg1.susp]);
+ device_printf(dev, " Charge termination: %s\n", e_d[reg1.term]);
+ device_printf(dev, " Charger reset: %s\n", i_a[reg1.reset]);
+ device_printf(dev, " NTC TYPE: %s\n", ntc_type_c[reg1.ntc_type]);
+ device_printf(dev, " Safety timer: %s\n", d_e[reg1.tmr_en]);
+ device_printf(dev, " Charge safety timer: %s\n", timer_c[reg1.timer]);
+
+ am335x_pmic_read(dev, TPS65217_CHGCONFIG2_REG, (uint8_t *)&reg2, 1);
+ device_printf(dev, " Charge voltage: %s\n", tps65217_voreg_c[reg2.voreg]);
+ device_printf(dev, " Pre-charge to fast charge transition voltage: %s\n",
+ vprechg_c[reg2.vprechg]);
+ device_printf(dev, " Dynamic timer function: %s\n", d_e[reg2.dyntmr]);
+
+ am335x_pmic_read(dev, TPS65217_CHGCONFIG3_REG, (uint8_t *)&reg3, 1);
+ device_printf(dev, " Temperature range for charging: %s\n", trange_c[reg3.trange]);
+ device_printf(dev, " Termination current factor: %s\n", termif_c[reg3.termif]);
+ device_printf(dev, " Pre-charge time: %s\n", pchrgt_c[reg3.pchrgt]);
+ device_printf(dev, " Power path DPPM threshold: %s\n", dppmth_c[reg3.dppmth]);
+ device_printf(dev, " Charge current: %s\n", ichrg_c[reg3.ichrg]);
+}
+
+static void
+am335x_pmic_setvo(device_t dev, uint8_t vo)
+{
+ struct tps65217_chgconfig2_reg reg2;
+
+ am335x_pmic_read(dev, TPS65217_CHGCONFIG2_REG, (uint8_t *)&reg2, 1);
+ reg2.voreg = vo;
+ am335x_pmic_write(dev, TPS65217_CHGCONFIG2_REG, (uint8_t *)&reg2, 1);
+}
+
+static void
am335x_pmic_start(void *xdev)
{
struct am335x_pmic_softc *sc;
device_t dev = (device_t)xdev;
- uint8_t reg;
+ struct tps65217_status_reg status_reg;
+ struct tps65217_chipid_reg chipid_reg;
+ uint8_t reg, vo;
char name[20];
- char pwr[4][11] = {"Unknown", "USB", "AC", "USB and AC"};
+ char pwr[4][11] = {"Battery", "USB", "AC", "USB and AC"};
int rv;
sc = device_get_softc(dev);
- am335x_pmic_read(dev, TPS65217_CHIPID_REG, &reg, 1);
- switch (reg>>4) {
+ am335x_pmic_read(dev, TPS65217_CHIPID_REG, (uint8_t *)&chipid_reg, 1);
+ switch (chipid_reg.chip) {
case TPS65217A:
- sprintf(name, "TPS65217A ver 1.%u", reg & 0xF);
+ sprintf(name, "TPS65217A ver 1.%u", chipid_reg.rev);
break;
case TPS65217B:
- sprintf(name, "TPS65217B ver 1.%u", reg & 0xF);
+ sprintf(name, "TPS65217B ver 1.%u", chipid_reg.rev);
break;
case TPS65217C:
- sprintf(name, "TPS65217C ver 1.%u", reg & 0xF);
+ sprintf(name, "TPS65217C ver 1.%u", chipid_reg.rev);
break;
case TPS65217D:
- sprintf(name, "TPS65217D ver 1.%u", reg & 0xF);
+ sprintf(name, "TPS65217D ver 1.%u", chipid_reg.rev);
break;
default:
sprintf(name, "Unknown PMIC");
}
- am335x_pmic_read(dev, TPS65217_STATUS_REG, &reg, 1);
- device_printf(dev, "%s powered by %s\n", name, pwr[(reg>>2)&0x03]);
+ am335x_pmic_read(dev, TPS65217_STATUS_REG, (uint8_t *)&status_reg, 1);
+ device_printf(dev, "%s powered by %s\n", name,
+ pwr[status_reg.usbpwr | (status_reg.acpwr << 1)]);
+
+ if (am335x_pmic_vo[0] != '\0') {
+ for (vo = 0; vo < 4; vo++) {
+ if (strcmp(tps65217_voreg_c[vo], am335x_pmic_vo) == 0)
+ break;
+ }
+ if (vo == 4) {
+ device_printf(dev, "WARNING: hw.am335x_pmic.vo=\"%s\""
+ ": unsupported value\n", am335x_pmic_vo);
+ } else {
+ am335x_pmic_setvo(dev, vo);
+ }
+ }
+
+ if (bootverbose || am335x_pmic_bootverbose) {
+ am335x_pmic_dump_chgconfig(dev);
+ }
EVENTHANDLER_REGISTER(shutdown_final, am335x_pmic_shutdown, dev,
SHUTDOWN_PRI_LAST);
@@ -248,14 +319,15 @@ static void
am335x_pmic_shutdown(void *xdev, int howto)
{
device_t dev;
- uint8_t reg;
+ struct tps65217_status_reg reg;
if (!(howto & RB_POWEROFF))
return;
dev = (device_t)xdev;
+ am335x_pmic_read(dev, TPS65217_STATUS_REG, (uint8_t *)&reg, 1);
/* Set the OFF bit on status register to start the shutdown sequence. */
- reg = TPS65217_STATUS_OFF;
- am335x_pmic_write(dev, TPS65217_STATUS_REG, &reg, 1);
+ reg.off = 1;
+ am335x_pmic_write(dev, TPS65217_STATUS_REG, (uint8_t *)&reg, 1);
/* Toggle pmic_pwr_enable to shutdown the PMIC. */
am335x_rtc_pmic_pwr_toggle();
}
diff --git a/sys/arm/ti/am335x/tps65217x.h b/sys/arm/ti/am335x/tps65217x.h
new file mode 100644
index 000000000000..cdeca2515df8
--- /dev/null
+++ b/sys/arm/ti/am335x/tps65217x.h
@@ -0,0 +1,114 @@
+/*-
+ * Copyright (c) 2012 Damjan Marion <dmarion@FreeBSD.org>
+ * Copyright (c) 2015 Maksym Sobolyev <sobomax@FreeBSD.org>
+ * 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$
+ */
+
+#ifndef __TPS65217X_H__
+#define __TPS65217X_H__
+
+/*
+ * TPS65217 PMIC is a companion chip for AM335x SoC sitting on I2C bus
+ */
+
+/* TPS65217 Registers */
+#define TPS65217_CHIPID_REG 0x00
+struct tps65217_chipid_reg {
+ unsigned int rev:4;
+ unsigned int chip:4;
+#define TPS65217A 0x7
+#define TPS65217B 0xF
+#define TPS65217C 0xE
+#define TPS65217D 0x6
+} __attribute__((__packed__));
+
+#define TPS65217_INT_REG 0x02
+struct tps65217_int_reg {
+ unsigned int usbi:1;
+ unsigned int aci:1;
+ unsigned int pbi:1;
+ unsigned int reserved3:1;
+ unsigned int usbm:1;
+ unsigned int acm:1;
+ unsigned int pbm:1;
+ unsigned int reserved7:1;
+} __attribute__((__packed__));
+
+#define TPS65217_STATUS_REG 0x0A
+struct tps65217_status_reg {
+ unsigned int pb:1;
+ unsigned int reserved1:1;
+ unsigned int usbpwr:1;
+ unsigned int acpwr:1;
+ unsigned int reserved4:3;
+ unsigned int off:1;
+} __attribute__((__packed__));
+
+#define TPS65217_CHGCONFIG0_REG 0x03
+struct tps65217_chgconfig0_reg {
+ unsigned int battemp:1;
+ unsigned int pchgtout:1;
+ unsigned int chgtout:1;
+ unsigned int active:1;
+ unsigned int termi:1;
+ unsigned int tsusp:1;
+ unsigned int dppm:1;
+ unsigned int treg:1;
+} __attribute__((__packed__));
+
+#define TPS65217_CHGCONFIG1_REG 0x04
+struct tps65217_chgconfig1_reg {
+ unsigned int chg_en:1;
+ unsigned int susp:1;
+ unsigned int term:1;
+ unsigned int reset:1;
+ unsigned int ntc_type:1;
+ unsigned int tmr_en:1;
+ unsigned int timer:2;
+} __attribute__((__packed__));
+
+#define TPS65217_CHGCONFIG2_REG 0x05
+struct tps65217_chgconfig2_reg {
+ unsigned int reserved:4;
+ unsigned int voreg:2;
+#define TPS65217_VO_410V 0b00
+#define TPS65217_VO_415V 0b01
+#define TPS65217_VO_420V 0b10
+#define TPS65217_VO_425V 0b11
+ unsigned int vprechg:1;
+ unsigned int dyntmr:1;
+} __attribute__((__packed__));
+
+#define TPS65217_CHGCONFIG3_REG 0x06
+struct tps65217_chgconfig3_reg {
+ unsigned int trange:1;
+ unsigned int termif:2;
+ unsigned int pchrgt:1;
+ unsigned int dppmth:2;
+ unsigned int ichrg:2;
+} __attribute__((__packed__));
+
+#endif /* __TPS65217X_H__ */
diff --git a/sys/arm64/acpica/OsdEnvironment.c b/sys/arm64/acpica/OsdEnvironment.c
new file mode 100644
index 000000000000..79dc212e4ec3
--- /dev/null
+++ b/sys/arm64/acpica/OsdEnvironment.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2000,2001 Michael Smith
+ * Copyright (c) 2000 BSDi
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/sysctl.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+static u_long acpi_root_phys;
+
+SYSCTL_ULONG(_machdep, OID_AUTO, acpi_root, CTLFLAG_RD, &acpi_root_phys, 0,
+ "The physical address of the RSDP");
+
+ACPI_STATUS
+AcpiOsInitialize(void)
+{
+
+ return (AE_OK);
+}
+
+ACPI_STATUS
+AcpiOsTerminate(void)
+{
+
+ return (AE_OK);
+}
+
+static u_long
+acpi_get_root_from_loader(void)
+{
+ long acpi_root;
+
+ if (resource_long_value("acpi", 0, "rsdp", &acpi_root) == 0)
+ return (acpi_root);
+
+ return (0);
+}
+
+ACPI_PHYSICAL_ADDRESS
+AcpiOsGetRootPointer(void)
+{
+
+ if (acpi_root_phys == 0)
+ acpi_root_phys = acpi_get_root_from_loader();
+
+ return (acpi_root_phys);
+}
diff --git a/sys/arm64/acpica/acpi_machdep.c b/sys/arm64/acpica/acpi_machdep.c
new file mode 100644
index 000000000000..da07cfcb0606
--- /dev/null
+++ b/sys/arm64/acpica/acpi_machdep.c
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2001 Mitsuru IWASAKI
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#include <dev/acpica/acpivar.h>
+
+int
+acpi_machdep_init(device_t dev)
+{
+
+ return (0);
+}
+
+int
+acpi_machdep_quirks(int *quirks)
+{
+
+ return (0);
+}
+
+static void *
+map_table(vm_paddr_t pa, int offset, const char *sig)
+{
+ ACPI_TABLE_HEADER *header;
+ vm_offset_t length;
+ void *table;
+
+ header = pmap_mapbios(pa, sizeof(ACPI_TABLE_HEADER));
+ if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) {
+ pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER));
+ return (NULL);
+ }
+ length = header->Length;
+ pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER));
+
+ table = pmap_mapbios(pa, length);
+ if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
+ if (bootverbose)
+ printf("ACPI: Failed checksum for table %s\n", sig);
+#if (ACPI_CHECKSUM_ABORT)
+ pmap_unmapbios(table, length);
+ return (NULL);
+#endif
+ }
+ return (table);
+}
+
+/*
+ * See if a given ACPI table is the requested table. Returns the
+ * length of the able if it matches or zero on failure.
+ */
+static int
+probe_table(vm_paddr_t address, const char *sig)
+{
+ ACPI_TABLE_HEADER *table;
+
+ table = pmap_mapbios(address, sizeof(ACPI_TABLE_HEADER));
+ if (table == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map table at 0x%jx\n",
+ (uintmax_t)address);
+ return (0);
+ }
+ if (bootverbose)
+ printf("Table '%.4s' at 0x%jx\n", table->Signature,
+ (uintmax_t)address);
+
+ if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) {
+ pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER));
+ return (0);
+ }
+ pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER));
+ return (1);
+}
+
+/* Unmap a table previously mapped via acpi_map_table(). */
+void
+acpi_unmap_table(void *table)
+{
+ ACPI_TABLE_HEADER *header;
+
+ header = (ACPI_TABLE_HEADER *)table;
+ pmap_unmapbios((vm_offset_t)table, header->Length);
+}
+
+/*
+ * Try to map a table at a given physical address previously returned
+ * by acpi_find_table().
+ */
+void *
+acpi_map_table(vm_paddr_t pa, const char *sig)
+{
+
+ return (map_table(pa, 0, sig));
+}
+
+/*
+ * Return the physical address of the requested table or zero if one
+ * is not found.
+ */
+vm_paddr_t
+acpi_find_table(const char *sig)
+{
+ ACPI_PHYSICAL_ADDRESS rsdp_ptr;
+ ACPI_TABLE_RSDP *rsdp;
+ ACPI_TABLE_XSDT *xsdt;
+ ACPI_TABLE_HEADER *table;
+ vm_paddr_t addr;
+ int i, count;
+
+ if (resource_disabled("acpi", 0))
+ return (0);
+
+ /*
+ * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn
+ * calls pmap_mapbios() to find the RSDP, we assume that we can use
+ * pmap_mapbios() to map the RSDP.
+ */
+ if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
+ return (0);
+ rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
+ if (rsdp == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map RSDP\n");
+ return (0);
+ }
+
+ addr = 0;
+ if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
+ /*
+ * AcpiOsGetRootPointer only verifies the checksum for
+ * the version 1.0 portion of the RSDP. Version 2.0 has
+ * an additional checksum that we verify first.
+ */
+ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
+ if (bootverbose)
+ printf("ACPI: RSDP failed extended checksum\n");
+ return (0);
+ }
+ xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
+ if (xsdt == NULL) {
+ if (bootverbose)
+ printf("ACPI: Failed to map XSDT\n");
+ pmap_unmapbios((vm_offset_t)rsdp,
+ sizeof(ACPI_TABLE_RSDP));
+ return (0);
+ }
+ count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
+ sizeof(UINT64);
+ for (i = 0; i < count; i++)
+ if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
+ addr = xsdt->TableOffsetEntry[i];
+ break;
+ }
+ acpi_unmap_table(xsdt);
+ }
+ pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP));
+
+ if (addr == 0) {
+ if (bootverbose)
+ printf("ACPI: No %s table found\n", sig);
+ return (0);
+ }
+ if (bootverbose)
+ printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr);
+
+ /*
+ * Verify that we can map the full table and that its checksum is
+ * correct, etc.
+ */
+ table = map_table(addr, 0, sig);
+ if (table == NULL)
+ return (0);
+ acpi_unmap_table(table);
+
+ return (addr);
+}
diff --git a/sys/arm64/acpica/acpi_wakeup.c b/sys/arm64/acpica/acpi_wakeup.c
new file mode 100644
index 000000000000..7724fddd0fde
--- /dev/null
+++ b/sys/arm64/acpica/acpi_wakeup.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+
+#include <dev/acpica/acpivar.h>
+
+/*
+ * ARM64TODO: Implement this.
+ */
+int
+acpi_sleep_machdep(struct acpi_softc *sc, int state)
+{
+
+ return (-1);
+}
+
+int
+acpi_wakeup_machdep(struct acpi_softc *sc, int state, int sleep_result,
+ int intr_enabled)
+{
+
+ /* ARM64TODO: We will need this with acpi_sleep_machdep */
+ KASSERT(sleep_result == -1,
+ ("acpi_wakeup_machdep: Invalid sleep result"));
+
+ return (sleep_result);
+}
diff --git a/sys/arm64/arm64/db_interface.c b/sys/arm64/arm64/db_interface.c
index 38834af19d1c..e40802fddaf7 100644
--- a/sys/arm64/arm64/db_interface.c
+++ b/sys/arm64/arm64/db_interface.c
@@ -156,13 +156,11 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data)
}
*dst++ = *data++;
}
+ dsb(ish);
- dsb();
/* Clean D-cache and invalidate I-cache */
cpu_dcache_wb_range(addr, (vm_size_t)size);
cpu_icache_sync_range(addr, (vm_size_t)size);
- dsb();
- isb();
return (0);
}
diff --git a/sys/arm64/arm64/db_trace.c b/sys/arm64/arm64/db_trace.c
index 1e89bac78b76..c60637783c2d 100644
--- a/sys/arm64/arm64/db_trace.c
+++ b/sys/arm64/arm64/db_trace.c
@@ -38,12 +38,7 @@ __FBSDID("$FreeBSD$");
#include <machine/armreg.h>
#include <machine/debug_monitor.h>
-
-struct unwind_state {
- uint64_t fp;
- uint64_t sp;
- uint64_t pc;
-};
+#include <machine/stack.h>
void
db_md_list_watchpoints()
@@ -67,22 +62,6 @@ db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
HW_BREAKPOINT_RW));
}
-static int
-db_unwind_frame(struct unwind_state *frame)
-{
- uint64_t fp = frame->fp;
-
- if (fp == 0)
- return -1;
-
- frame->sp = fp + 0x10;
- /* FP to previous frame (X29) */
- frame->fp = *(uint64_t *)(fp);
- /* LR (X30) */
- frame->pc = *(uint64_t *)(fp + 8) - 4;
- return (0);
-}
-
static void
db_stack_trace_cmd(struct unwind_state *frame)
{
@@ -95,7 +74,7 @@ db_stack_trace_cmd(struct unwind_state *frame)
uint64_t pc = frame->pc;
int ret;
- ret = db_unwind_frame(frame);
+ ret = unwind_frame(frame);
if (ret < 0)
break;
diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S
index efb13645c08c..9568075edc94 100644
--- a/sys/arm64/arm64/exception.S
+++ b/sys/arm64/arm64/exception.S
@@ -33,6 +33,9 @@ __FBSDID("$FreeBSD$");
.text
.macro save_registers el
+.if \el == 1
+ mov x18, sp
+.endif
stp x28, x29, [sp, #-16]!
stp x26, x27, [sp, #-16]!
stp x24, x25, [sp, #-16]!
@@ -51,22 +54,20 @@ __FBSDID("$FreeBSD$");
mrs x10, elr_el1
mrs x11, spsr_el1
.if \el == 0
- mrs x12, sp_el0
-.else
- mov x12, sp
+ mrs x18, sp_el0
.endif
stp x10, x11, [sp, #-16]!
- stp x12, lr, [sp, #-16]!
+ stp x18, lr, [sp, #-16]!
mrs x18, tpidr_el1
.endm
.macro restore_registers el
- ldp x12, lr, [sp], #16
+ msr daifset, #2 /* Disable interrupts, x18 may change
+ * in the interrupt exception handler */
+ ldp x18, lr, [sp], #16
ldp x10, x11, [sp], #16
.if \el == 0
- msr sp_el0, x12
-.else
- mov sp, x12
+ msr sp_el0, x18
.endif
msr spsr_el1, x11
msr elr_el1, x10
@@ -89,6 +90,10 @@ __FBSDID("$FreeBSD$");
ldp x24, x25, [sp], #16
ldp x26, x27, [sp], #16
ldp x28, x29, [sp], #16
+.if \el == 1
+ mov sp, x18
+ mrs x18, tpidr_el1
+.endif
.endm
.macro do_ast
diff --git a/sys/arm64/arm64/gic.c b/sys/arm64/arm64/gic.c
index 59fac99d7bee..7c0692ea790a 100644
--- a/sys/arm64/arm64/gic.c
+++ b/sys/arm64/arm64/gic.c
@@ -51,11 +51,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include <machine/smp.h>
-#include <dev/fdt/fdt_common.h>
-#include <dev/ofw/openfirm.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
+#include <arm64/arm64/gic.h>
#include "pic_if.h"
@@ -102,18 +98,6 @@ __FBSDID("$FreeBSD$");
#define GICD_ICFGR_TRIG_EDGE (1 << 1)
#define GICD_ICFGR_TRIG_MASK 0x2
-struct arm_gic_softc {
- device_t gic_dev;
- struct resource * gic_res[3];
- bus_space_tag_t gic_c_bst;
- bus_space_tag_t gic_d_bst;
- bus_space_handle_t gic_c_bsh;
- bus_space_handle_t gic_d_bsh;
- uint8_t ver;
- struct mtx mutex;
- uint32_t nirqs;
-};
-
static struct resource_spec arm_gic_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Distributor registers */
{ SYS_RES_MEMORY, 1, RF_ACTIVE }, /* CPU Interrupt Intf. registers */
@@ -136,31 +120,6 @@ static pic_eoi_t gic_eoi;
static pic_mask_t gic_mask_irq;
static pic_unmask_t gic_unmask_irq;
-static struct ofw_compat_data compat_data[] = {
- {"arm,gic", true}, /* Non-standard, used in FreeBSD dts. */
- {"arm,gic-400", true},
- {"arm,cortex-a15-gic", true},
- {"arm,cortex-a9-gic", true},
- {"arm,cortex-a7-gic", true},
- {"arm,arm11mp-gic", true},
- {"brcm,brahma-b15-gic", true},
- {NULL, false}
-};
-
-static int
-arm_gic_probe(device_t dev)
-{
-
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
- return (ENXIO);
-
- device_set_desc(dev, "ARM Generic Interrupt Controller");
- return (BUS_PROBE_DEFAULT);
-}
-
#ifdef SMP
static void
gic_init_secondary(device_t dev)
@@ -367,7 +326,6 @@ arm_gic_ipi_clear(device_t dev, int ipi)
static device_method_t arm_gic_methods[] = {
/* Device interface */
- DEVMETHOD(device_probe, arm_gic_probe),
DEVMETHOD(device_attach, arm_gic_attach),
/* pic_if */
@@ -384,15 +342,5 @@ static device_method_t arm_gic_methods[] = {
{ 0, 0 }
};
-static driver_t arm_gic_driver = {
- "gic",
- arm_gic_methods,
- sizeof(struct arm_gic_softc),
-};
-
-static devclass_t arm_gic_devclass;
-
-EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0,
- BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
-EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0,
- BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods,
+ sizeof(struct arm_gic_softc));
diff --git a/sys/arm64/arm64/gic.h b/sys/arm64/arm64/gic.h
new file mode 100644
index 000000000000..2660884291ea
--- /dev/null
+++ b/sys/arm64/arm64/gic.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * Copyright (c) 2014 Andrew Turner
+ * All rights reserved.
+ *
+ * Developed by Damjan Marion <damjan.marion@gmail.com>
+ *
+ * Based on OMAP4 GIC code by Ben Gray
+ *
+ * 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. The name of the company nor the name of the author may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * 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$
+ */
+
+#ifndef _ARM64_GIC_H_
+#define _ARM64_GIC_H_
+
+DECLARE_CLASS(arm_gic_driver);
+
+struct arm_gic_softc {
+ device_t gic_dev;
+ struct resource * gic_res[3];
+ bus_space_tag_t gic_c_bst;
+ bus_space_tag_t gic_d_bst;
+ bus_space_handle_t gic_c_bsh;
+ bus_space_handle_t gic_d_bsh;
+ uint8_t ver;
+ struct mtx mutex;
+ uint32_t nirqs;
+};
+
+#endif
diff --git a/sys/arm64/arm64/gic_acpi.c b/sys/arm64/arm64/gic_acpi.c
new file mode 100644
index 000000000000..ad26c0c43bcd
--- /dev/null
+++ b/sys/arm64/arm64/gic_acpi.c
@@ -0,0 +1,161 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <arm64/arm64/gic.h>
+
+#include <contrib/dev/acpica/include/acpi.h>
+
+#include <dev/acpica/acpivar.h>
+
+struct arm_gic_acpi_softc {
+ struct arm_gic_softc gic_sc;
+ struct resource_list res;
+};
+
+struct madt_table_data {
+ device_t parent;
+ ACPI_MADT_GENERIC_DISTRIBUTOR *dist;
+ ACPI_MADT_GENERIC_INTERRUPT *intr;
+};
+
+static void
+madt_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
+{
+ struct madt_table_data *madt_data;
+
+ madt_data = (struct madt_table_data *)arg;
+
+ switch(entry->Type) {
+ case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
+ if (madt_data->intr != NULL) {
+ if (bootverbose)
+ device_printf(madt_data->parent,
+ "gic: Already have an interrupt table");
+ break;
+ }
+
+ madt_data->intr = (ACPI_MADT_GENERIC_INTERRUPT *)entry;
+ break;
+
+ case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
+ if (madt_data->dist != NULL) {
+ if (bootverbose)
+ device_printf(madt_data->parent,
+ "gic: Already have a distributor table");
+ break;
+ }
+
+ madt_data->dist = (ACPI_MADT_GENERIC_DISTRIBUTOR *)entry;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+arm_gic_acpi_identify(driver_t *driver, device_t parent)
+{
+ struct madt_table_data madt_data;
+ ACPI_TABLE_MADT *madt;
+ vm_paddr_t physaddr;
+ device_t dev;
+
+ physaddr = acpi_find_table(ACPI_SIG_MADT);
+ if (physaddr == 0)
+ return;
+
+ madt = acpi_map_table(physaddr, ACPI_SIG_MADT);
+ if (madt == NULL) {
+ device_printf(parent, "gic: Unable to map the MADT\n");
+ return;
+ }
+
+ madt_data.parent = parent;
+ madt_data.dist = NULL;
+ madt_data.intr = NULL;
+
+ acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length,
+ madt_handler, &madt_data);
+ if (madt_data.intr == NULL || madt_data.dist == NULL) {
+ device_printf(parent,
+ "No gic interrupt or distributor table\n");
+ goto out;
+ }
+
+ dev = BUS_ADD_CHILD(parent, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE,
+ "gic", -1);
+ if (dev == NULL) {
+ device_printf(parent, "add gic child failed\n");
+ goto out;
+ }
+
+ /* Add the MADT data */
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 0,
+ madt_data.dist->BaseAddress, PAGE_SIZE);
+ BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 1,
+ madt_data.intr->BaseAddress, PAGE_SIZE);
+
+out:
+ acpi_unmap_table(madt);
+}
+
+static int
+arm_gic_acpi_probe(device_t dev)
+{
+
+ device_set_desc(dev, "ARM Generic Interrupt Controller");
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static device_method_t arm_gic_acpi_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_identify, arm_gic_acpi_identify),
+ DEVMETHOD(device_probe, arm_gic_acpi_probe),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(gic, arm_gic_acpi_driver, arm_gic_acpi_methods,
+ sizeof(struct arm_gic_acpi_softc), arm_gic_driver);
+
+static devclass_t arm_gic_acpi_devclass;
+
+EARLY_DRIVER_MODULE(gic, acpi, arm_gic_acpi_driver,
+ arm_gic_acpi_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/arm64/arm64/gic_fdt.c b/sys/arm64/arm64/gic_fdt.c
new file mode 100644
index 000000000000..5b70624d7362
--- /dev/null
+++ b/sys/arm64/arm64/gic_fdt.c
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm64/arm64/gic.h>
+
+static struct ofw_compat_data compat_data[] = {
+ {"arm,gic", true}, /* Non-standard, used in FreeBSD dts. */
+ {"arm,gic-400", true},
+ {"arm,cortex-a15-gic", true},
+ {"arm,cortex-a9-gic", true},
+ {"arm,cortex-a7-gic", true},
+ {"arm,arm11mp-gic", true},
+ {"brcm,brahma-b15-gic", true},
+ {NULL, false}
+};
+
+static int
+arm_gic_fdt_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
+ return (ENXIO);
+
+ device_set_desc(dev, "ARM Generic Interrupt Controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static device_method_t arm_gic_fdt_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, arm_gic_fdt_probe),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(gic, arm_gic_fdt_driver, arm_gic_fdt_methods,
+ sizeof(struct arm_gic_softc), arm_gic_driver);
+
+static devclass_t arm_gic_fdt_devclass;
+
+EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_fdt_driver,
+ arm_gic_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_fdt_driver, arm_gic_fdt_devclass,
+ 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index 221b138529d9..c36769d1d84f 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -392,6 +392,8 @@ cpu_est_clockrate(int cpu_id, uint64_t *rate)
void
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
{
+
+ pcpu->pc_acpi_id = 0xffffffff;
}
void
diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c
index d6c6d2b69f69..764012e94154 100644
--- a/sys/arm64/arm64/nexus.c
+++ b/sys/arm64/arm64/nexus.c
@@ -60,12 +60,17 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/intr.h>
+#include "opt_acpi.h"
#include "opt_platform.h"
#ifdef FDT
#include <dev/fdt/fdt_common.h>
#include "ofw_bus_if.h"
#endif
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#include <dev/acpica/acpivar.h>
+#endif
extern struct bus_space memmap_bus;
@@ -78,9 +83,19 @@ struct nexus_device {
#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev))
static struct rman mem_rman;
+static struct rman irq_rman;
-static int nexus_probe(device_t);
static int nexus_attach(device_t);
+
+#ifdef FDT
+static device_probe_t nexus_fdt_probe;
+static device_attach_t nexus_fdt_attach;
+#endif
+#ifdef DEV_ACPI
+static device_probe_t nexus_acpi_probe;
+static device_attach_t nexus_acpi_attach;
+#endif
+
static int nexus_print_child(device_t, device_t);
static device_t nexus_add_child(device_t, u_int, const char *, int);
static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
@@ -89,6 +104,8 @@ static int nexus_activate_resource(device_t, device_t, int, int,
struct resource *);
static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
enum intr_polarity pol);
+static struct resource_list *nexus_get_reslist(device_t, device_t);
+static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long);
static int nexus_deactivate_resource(device_t, device_t, int, int,
struct resource *);
@@ -102,21 +119,18 @@ static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent,
#endif
static device_method_t nexus_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, nexus_probe),
- DEVMETHOD(device_attach, nexus_attach),
/* Bus interface */
DEVMETHOD(bus_print_child, nexus_print_child),
DEVMETHOD(bus_add_child, nexus_add_child),
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
DEVMETHOD(bus_config_intr, nexus_config_intr),
+ DEVMETHOD(bus_get_resource_list, nexus_get_reslist),
+ DEVMETHOD(bus_set_resource, nexus_set_resource),
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
-#ifdef FDT
- DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
-#endif
+
{ 0, 0 }
};
@@ -129,15 +143,6 @@ static driver_t nexus_driver = {
DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
static int
-nexus_probe(device_t dev)
-{
-
- device_quiet(dev); /* suppress attach message for neatness */
-
- return (BUS_PROBE_DEFAULT);
-}
-
-static int
nexus_attach(device_t dev)
{
@@ -146,15 +151,14 @@ nexus_attach(device_t dev)
mem_rman.rm_type = RMAN_ARRAY;
mem_rman.rm_descr = "I/O memory addresses";
if (rman_init(&mem_rman) || rman_manage_region(&mem_rman, 0, ~0))
- panic("nexus_probe mem_rman");
-
- /* Add the ofwbus device */
- /* ARM64TODO: Alternatively add acpi */
- nexus_add_child(dev, 10, "ofwbus", 0);
+ panic("nexus_attach mem_rman");
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = ~0ul;
+ irq_rman.rm_type = RMAN_ARRAY;
+ irq_rman.rm_descr = "Interrupts";
+ if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, 0, ~0))
+ panic("nexus_attach irq_rman");
- /*
- * First, deal with the children we know about already
- */
bus_generic_probe(dev);
bus_generic_attach(dev);
@@ -201,11 +205,34 @@ static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
+ struct nexus_device *ndev = DEVTONX(child);
struct resource *rv;
+ struct resource_list_entry *rle;
struct rman *rm;
int needactivate = flags & RF_ACTIVE;
+ /*
+ * If this is an allocation of the "default" range for a given
+ * RID, and we know what the resources for this device are
+ * (ie. they aren't maintained by a child bus), then work out
+ * the start/end values.
+ */
+ if ((start == 0UL) && (end == ~0UL) && (count == 1)) {
+ if (device_get_parent(child) != bus || ndev == NULL)
+ return(NULL);
+ rle = resource_list_find(&ndev->nx_resources, type, *rid);
+ if (rle == NULL)
+ return(NULL);
+ start = rle->start;
+ end = rle->end;
+ count = rle->count;
+ }
+
switch (type) {
+ case SYS_RES_IRQ:
+ rm = &irq_rman;
+ break;
+
case SYS_RES_MEMORY:
case SYS_RES_IOPORT:
rm = &mem_rman;
@@ -297,6 +324,28 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid,
return (0);
}
+static struct resource_list *
+nexus_get_reslist(device_t dev, device_t child)
+{
+ struct nexus_device *ndev = DEVTONX(child);
+
+ return (&ndev->nx_resources);
+}
+
+static int
+nexus_set_resource(device_t dev, device_t child, int type, int rid,
+ u_long start, u_long count)
+{
+ struct nexus_device *ndev = DEVTONX(child);
+ struct resource_list *rl = &ndev->nx_resources;
+
+ /* XXX this should return a success/failure indicator */
+ resource_list_add(rl, type, rid, start, start + count - 1, count);
+
+ return(0);
+}
+
+
static int
nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
@@ -317,6 +366,41 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
}
#ifdef FDT
+static device_method_t nexus_fdt_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_fdt_probe),
+ DEVMETHOD(device_attach, nexus_fdt_attach),
+
+ /* OFW interface */
+ DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
+};
+
+#define nexus_baseclasses nexus_fdt_baseclasses
+DEFINE_CLASS_1(nexus, nexus_fdt_driver, nexus_fdt_methods, 1, nexus_driver);
+#undef nexus_baseclasses
+static devclass_t nexus_fdt_devclass;
+
+DRIVER_MODULE(nexus_fdt, root, nexus_fdt_driver, nexus_fdt_devclass, 0, 0);
+
+static int
+nexus_fdt_probe(device_t dev)
+{
+
+ if (OF_peer(0) == 0)
+ return (ENXIO);
+
+ device_quiet(dev);
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+nexus_fdt_attach(device_t dev)
+{
+
+ nexus_add_child(dev, 10, "ofwbus", 0);
+ return (nexus_attach(dev));
+}
+
static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
pcell_t *intr)
@@ -336,3 +420,37 @@ nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
}
#endif
+#ifdef DEV_ACPI
+static device_method_t nexus_acpi_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_acpi_probe),
+ DEVMETHOD(device_attach, nexus_acpi_attach),
+};
+
+#define nexus_baseclasses nexus_acpi_baseclasses
+DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1,
+ nexus_driver);
+#undef nexus_baseclasses
+static devclass_t nexus_acpi_devclass;
+
+DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_acpi_devclass, 0, 0);
+
+static int
+nexus_acpi_probe(device_t dev)
+{
+
+ if (acpi_identify() != 0)
+ return (ENXIO);
+
+ device_quiet(dev);
+ return (BUS_PROBE_LOW_PRIORITY);
+}
+
+static int
+nexus_acpi_attach(device_t dev)
+{
+
+ nexus_add_child(dev, 10, "acpi", 0);
+ return (nexus_attach(dev));
+}
+#endif
diff --git a/sys/arm64/arm64/unwind.c b/sys/arm64/arm64/unwind.c
new file mode 100644
index 000000000000..13e0b548add1
--- /dev/null
+++ b/sys/arm64/arm64/unwind.c
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+
+#include <machine/stack.h>
+
+int
+unwind_frame(struct unwind_state *frame)
+{
+ uint64_t fp;
+
+ fp = frame->fp;
+ if (fp == 0)
+ return (-1);
+
+ frame->sp = fp + 0x10;
+ /* FP to previous frame (X29) */
+ frame->fp = *(uint64_t *)(fp);
+ /* LR (X30) */
+ frame->pc = *(uint64_t *)(fp + 8) - 4;
+
+ return (0);
+}
diff --git a/sys/arm64/arm64/vfp.c b/sys/arm64/arm64/vfp.c
index 7ce59b8d5667..5e44d5e83f36 100644
--- a/sys/arm64/arm64/vfp.c
+++ b/sys/arm64/arm64/vfp.c
@@ -120,7 +120,7 @@ vfp_save_state(struct thread *td)
td->td_pcb->pcb_fpcr = fpcr;
td->td_pcb->pcb_fpsr = fpsr;
- dsb();
+ dsb(ish);
vfp_disable();
}
critical_exit();
diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC
index 8e20d6004d11..4eae4dfce7a4 100644
--- a/sys/arm64/conf/GENERIC
+++ b/sys/arm64/conf/GENERIC
@@ -95,3 +95,4 @@ device psci # Support for ARM PSCI
device bpf # Berkeley packet filter
options FDT
+device acpi
diff --git a/sys/arm64/include/acpica_machdep.h b/sys/arm64/include/acpica_machdep.h
new file mode 100644
index 000000000000..9a3434a2bbab
--- /dev/null
+++ b/sys/arm64/include/acpica_machdep.h
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2002 Mitsuru IWASAKI
+ * 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$
+ */
+
+/******************************************************************************
+ *
+ * Name: acpica_machdep.h - arch-specific defines, etc.
+ * $Revision$
+ *
+ *****************************************************************************/
+
+#ifndef __ACPICA_MACHDEP_H__
+#define __ACPICA_MACHDEP_H__
+
+
+#ifdef _KERNEL
+
+/* Only use the reduced hardware model */
+#define ACPI_REDUCED_HARDWARE 1
+
+/* Section 5.2.10.1: global lock acquire/release functions */
+int acpi_acquire_global_lock(volatile uint32_t *);
+int acpi_release_global_lock(volatile uint32_t *);
+
+void *acpi_map_table(vm_paddr_t pa, const char *sig);
+void acpi_unmap_table(void *table);
+vm_paddr_t acpi_find_table(const char *sig);
+
+#endif /* _KERNEL */
+
+#endif /* __ACPICA_MACHDEP_H__ */
diff --git a/sys/arm64/include/atomic.h b/sys/arm64/include/atomic.h
index f0f6c17c73c6..99252b8f6800 100644
--- a/sys/arm64/include/atomic.h
+++ b/sys/arm64/include/atomic.h
@@ -29,13 +29,29 @@
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
-#define isb() __asm __volatile("isb" : : : "memory")
-#define dsb() __asm __volatile("dsb sy" : : : "memory")
-#define dmb() __asm __volatile("dmb sy" : : : "memory")
+#define isb() __asm __volatile("isb" : : : "memory")
-#define mb() dmb()
-#define wmb() dmb()
-#define rmb() dmb()
+/*
+ * Options for DMB and DSB:
+ * oshld Outer Shareable, load
+ * oshst Outer Shareable, store
+ * osh Outer Shareable, all
+ * nshld Non-shareable, load
+ * nshst Non-shareable, store
+ * nsh Non-shareable, all
+ * ishld Inner Shareable, load
+ * ishst Inner Shareable, store
+ * ish Inner Shareable, all
+ * ld Full system, load
+ * st Full system, store
+ * sy Full system, all
+ */
+#define dsb(opt) __asm __volatile("dsb " __STRING(opt) : : : "memory")
+#define dmb(opt) __asm __volatile("dmb " __STRING(opt) : : : "memory")
+
+#define mb() dmb(sy) /* Full system memory barrier all */
+#define wmb() dmb(st) /* Full system memory barrier store */
+#define rmb() dmb(ld) /* Full system memory barrier load */
static __inline void
atomic_add_32(volatile uint32_t *p, uint32_t val)
diff --git a/sys/arm64/include/iodev.h b/sys/arm64/include/iodev.h
new file mode 100644
index 000000000000..5521ff71bc5f
--- /dev/null
+++ b/sys/arm64/include/iodev.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2015 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Andrew Turner under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * 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$
+ */
+
+#ifndef _MACHINE_IODEV_H_
+#define _MACHINE_IODEV_H_
+
+#define iodev_read_1(a) \
+({ \
+ uint8_t val; \
+ __asm __volatile("ldrb %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
+
+#define iodev_read_2(a) \
+({ \
+ uint16_t val; \
+ __asm __volatile("ldrh %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
+
+#define iodev_read_4(a) \
+({ \
+ uint32_t val; \
+ __asm __volatile("ldr %w0, [%1]" : "=&r" (val) : "r"(a)); \
+ val; \
+})
+
+#define iodev_write_1(a, v) \
+ __asm __volatile("strb %w0, [%1]" :: "r" (v), "r"(a))
+
+#define iodev_write_2(a, v) \
+ __asm __volatile("strh %w0, [%1]" :: "r" (v), "r"(a))
+
+#define iodev_write_4(a, v) \
+ __asm __volatile("str %w0, [%1]" :: "r" (v), "r"(a))
+
+#endif /* _MACHINE_IODEV_H_ */
diff --git a/sys/arm64/include/pci_cfgreg.h b/sys/arm64/include/pci_cfgreg.h
new file mode 100644
index 000000000000..da23dbe43a4f
--- /dev/null
+++ b/sys/arm64/include/pci_cfgreg.h
@@ -0,0 +1 @@
+/* $FreeBSD$ */
diff --git a/sys/arm64/include/pcpu.h b/sys/arm64/include/pcpu.h
index 6de3e8958735..19cd7586b4d1 100644
--- a/sys/arm64/include/pcpu.h
+++ b/sys/arm64/include/pcpu.h
@@ -36,7 +36,8 @@
#define ALT_STACK_SIZE 128
#define PCPU_MD_FIELDS \
- char __pad[129]
+ u_int pc_acpi_id; /* ACPI CPU id */ \
+ char __pad[125]
#ifdef _KERNEL
diff --git a/sys/arm64/include/stack.h b/sys/arm64/include/stack.h
index 8131ce5c3baf..db0d4ab38d4d 100644
--- a/sys/arm64/include/stack.h
+++ b/sys/arm64/include/stack.h
@@ -32,4 +32,12 @@
#define INKERNEL(va) \
((va) >= VM_MIN_KERNEL_ADDRESS && (va) <= VM_MAX_KERNEL_ADDRESS)
+struct unwind_state {
+ uint64_t fp;
+ uint64_t sp;
+ uint64_t pc;
+};
+
+int unwind_frame(struct unwind_state *);
+
#endif /* !_MACHINE_STACK_H_ */
diff --git a/sys/arm64/include/vmparam.h b/sys/arm64/include/vmparam.h
index 2065fda7dbe2..9a2d6e544596 100644
--- a/sys/arm64/include/vmparam.h
+++ b/sys/arm64/include/vmparam.h
@@ -75,13 +75,12 @@
#define VM_PHYSSEG_MAX 64
/*
- * Create three free page pools: VM_FREEPOOL_DEFAULT is the default pool
+ * Create two free page pools: VM_FREEPOOL_DEFAULT is the default pool
* from which physical pages are allocated and VM_FREEPOOL_DIRECT is
* the pool from which physical pages for small UMA objects are
* allocated.
*/
-#define VM_NFREEPOOL 3
-#define VM_FREEPOOL_CACHE 2
+#define VM_NFREEPOOL 2
#define VM_FREEPOOL_DEFAULT 0
#define VM_FREEPOOL_DIRECT 1
diff --git a/sys/boot/efi/libefi/Makefile.depend b/sys/boot/efi/libefi/Makefile.depend
index e248139c3a0e..c77da59895bc 100644
--- a/sys/boot/efi/libefi/Makefile.depend
+++ b/sys/boot/efi/libefi/Makefile.depend
@@ -1,3 +1,4 @@
+# $FreeBSD$
# Autogenerated - do NOT edit!
DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
diff --git a/sys/boot/efi/loader/arch/arm64/exec.c b/sys/boot/efi/loader/arch/arm64/exec.c
index 1f722695d160..d13e97b70819 100644
--- a/sys/boot/efi/loader/arch/arm64/exec.c
+++ b/sys/boot/efi/loader/arch/arm64/exec.c
@@ -42,6 +42,15 @@ __FBSDID("$FreeBSD$");
#include "loader_efi.h"
#include "cache.h"
+#include "platform/acfreebsd.h"
+#include "acconfig.h"
+#define ACPI_SYSTEM_XFACE
+#include "actypes.h"
+#include "actbl.h"
+
+static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
+static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
+
static int elf64_exec(struct preloaded_file *amp);
static int elf64_obj_exec(struct preloaded_file *amp);
@@ -64,12 +73,41 @@ elf64_exec(struct preloaded_file *fp)
vm_offset_t clean_addr;
size_t clean_size;
struct file_metadata *md;
+ ACPI_TABLE_RSDP *rsdp;
EFI_STATUS status;
EFI_PHYSICAL_ADDRESS addr;
Elf_Ehdr *ehdr;
- int err;
+ char buf[24];
+ int err, revision;
void (*entry)(vm_offset_t);
+ rsdp = efi_get_table(&acpi20_guid);
+ if (rsdp == NULL) {
+ rsdp = efi_get_table(&acpi_guid);
+ }
+ if (rsdp != NULL) {
+ sprintf(buf, "0x%016llx", (unsigned long long)rsdp);
+ setenv("hint.acpi.0.rsdp", buf, 1);
+ revision = rsdp->Revision;
+ if (revision == 0)
+ revision = 1;
+ sprintf(buf, "%d", revision);
+ setenv("hint.acpi.0.revision", buf, 1);
+ strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId));
+ buf[sizeof(rsdp->OemId)] = '\0';
+ setenv("hint.acpi.0.oem", buf, 1);
+ sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress);
+ setenv("hint.acpi.0.rsdt", buf, 1);
+ if (revision >= 2) {
+ /* XXX extended checksum? */
+ sprintf(buf, "0x%016llx",
+ (unsigned long long)rsdp->XsdtPhysicalAddress);
+ setenv("hint.acpi.0.xsdt", buf, 1);
+ sprintf(buf, "%d", rsdp->Length);
+ setenv("hint.acpi.0.xsdt_length", buf, 1);
+ }
+ }
+
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE);
diff --git a/sys/boot/fdt/dts/arm/meson3.dtsi b/sys/boot/fdt/dts/arm/meson3.dtsi
new file mode 100644
index 000000000000..444e3cf62e9e
--- /dev/null
+++ b/sys/boot/fdt/dts/arm/meson3.dtsi
@@ -0,0 +1,77 @@
+/*-
+ * Copyright (c) 2015 John Wehle <john@feith.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$
+ */
+
+/*
+ * The basic single core aml8726 (aka meson) uses an Amlogic interrupt
+ * controller, however meson.dtsi specifies GIC (which is present on
+ * the multicore aml8726) so we need to override things here.
+ */
+
+/include/ "meson.dtsi"
+
+/ {
+ model = "Amlogic Meson3 SoC";
+ compatible = "amlogic,meson3";
+
+ interrupt-parent = <&pic>;
+
+ pic: pic@c1109a40 {
+ device_type = "interrupt-controller";
+ compatible = "amlogic,aml8726-pic";
+ reg = <0xc1109a40 128>; /* cbus 0x2690 */
+
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x200>;
+ };
+ };
+
+ clk81: clk@0 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+};
+
+&gic {
+ status = "disabled";
+};
+
+&L2 {
+ interrupts = <0 61 1>;
+};
diff --git a/sys/boot/fdt/dts/arm/sun4i-a10.dtsi b/sys/boot/fdt/dts/arm/sun4i-a10.dtsi
index 087e3140f30f..0d554f2b545a 100644
--- a/sys/boot/fdt/dts/arm/sun4i-a10.dtsi
+++ b/sys/boot/fdt/dts/arm/sun4i-a10.dtsi
@@ -127,7 +127,6 @@
current-speed = <115200>;
clock-frequency = < 24000000 >;
busy-detect = <1>;
- broken-txfifo = <1>;
};
emac@01c0b000 {
diff --git a/sys/boot/fdt/dts/arm/sun7i-a20.dtsi b/sys/boot/fdt/dts/arm/sun7i-a20.dtsi
index 7dd894725772..fa60c38e8518 100644
--- a/sys/boot/fdt/dts/arm/sun7i-a20.dtsi
+++ b/sys/boot/fdt/dts/arm/sun7i-a20.dtsi
@@ -133,7 +133,6 @@
current-speed = <115200>;
clock-frequency = < 24000000 >;
busy-detect = <1>;
- broken-txfifo = <1>;
};
emac@01c0b000 {
diff --git a/sys/boot/fdt/dts/arm/vsatv102-m6.dts b/sys/boot/fdt/dts/arm/vsatv102-m6.dts
index 786f80a43223..468d5f0096d5 100644
--- a/sys/boot/fdt/dts/arm/vsatv102-m6.dts
+++ b/sys/boot/fdt/dts/arm/vsatv102-m6.dts
@@ -282,6 +282,17 @@
};
};
+ leds {
+ compatible = "gpio-leds";
+
+ sys_led {
+ gpios = <&gpioao 2>; /* gpioao_2 sys_led */
+ label = "sys_led";
+
+ default-state = "on";
+ };
+ };
+
chosen {
stdin = "uart0";
stdout = "uart0";
diff --git a/sys/boot/fdt/dts/arm/yyhd18-m3.dts b/sys/boot/fdt/dts/arm/yyhd18-m3.dts
new file mode 100644
index 000000000000..bdb425d034c0
--- /dev/null
+++ b/sys/boot/fdt/dts/arm/yyhd18-m3.dts
@@ -0,0 +1,237 @@
+/*-
+ * Copyright (c) 2015 John Wehle <john@feith.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$
+ */
+
+/*
+ * The ordering of certain devices is significant (e.g. usb depends on
+ * usb-phy which depends on gpio, also the timer should appear early on
+ * to provide a reasonably accurate DELAY implementation).
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x84900000 0x00600000; /* 6MB frame buffer */
+
+#include "meson3.dtsi"
+
+/ {
+ /*
+ * My development unit is a Yiyate Android TV Box containing
+ * a HD18 motherboard and an aml8726-m3 SoC ... later versions
+ * shipped with an aml8726-m6. Printenv in uboot shows m3-oplay
+ * as the boardname supplied as part of mmcargs.
+ */
+
+ model = "yiyate,hd18-m3";
+ compatible = "yiyate,hd18-m3", "amlogic,meson3";
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ soc = &soc;
+ screen = &screen;
+ uart0 = &uart_AO;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1GB RAM */
+ };
+
+ soc: soc {
+ device_type = "soc";
+ bus-frequency = <0>;
+
+ ccm@c1104140 {
+ compatible = "amlogic,aml8726-ccm";
+ reg = <0xc1104140 20>; /* cbus 0x1050 */
+
+ functions = "ethernet", "i2c", "rng", "sdio",
+ "uart-a", "uart-b", "uart-c",
+ "usb-a", "usb-b";
+ };
+
+ pinctrl: pinctrl@c11080b0 {
+ compatible = "amlogic,aml8726-pinctrl";
+ reg = <0xc11080b0 40>, /* mux */
+ <0xc11080e8 24>, /* pu/pd */
+ <0xc11080e8 24>, /* pull enable */
+ <0xc8100014 4>, /* ao mux */
+ <0xc810002c 4>, /* ao pu/pd */
+ <0xc810002c 4>; /* ao pull enable */
+
+ /*
+ * Currently only pin muxing that deviates
+ * from the power on default of gpio is
+ * specified here.
+ */
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_uartao &pins_ethernet &pins_hdmi>;
+
+ pins_ethernet: ethernet {
+ amlogic,pins = "clk_out", "tx_en",
+ "tx_d0", "tx_d1",
+ "crs_dv", "rx_err",
+ "rx_d0", "rx_d1",
+ "mdc", "mdio";
+ amlogic,function = "ethernet";
+ };
+
+ pins_hdmi: hdmi {
+ amlogic,pins = "cec", "hpd",
+ "scl", "sda";
+ amlogic,function = "hdmi";
+ };
+
+ pins_sdio_b: sdio_b {
+ amlogic,pins = "clk", "cmd",
+ "d0", "d1",
+ "d2", "d3";
+ amlogic,function = "sdio-b";
+ };
+
+ pins_uartao: uartao {
+ amlogic,pins = "tx", "rx";
+ amlogic,function = "uart-ao";
+ };
+ };
+
+ rtc@c8100740 {
+ compatible = "amlogic,aml8726-rtc";
+ reg = <0xc8100740 20>; /* aobus 0x1d0 */
+ interrupts = <0 72 1>; /* AM_IRQ2(8) */
+ };
+
+ clkmsr: clkmsr@c1108758 {
+ compatible = "amlogic,aml8726-clkmsr";
+ reg = <0xc1108758 16>; /* cbus 0x21d6 */
+
+ clocks = <&clk81>;
+ };
+
+ gpio5: gpio@c110806c {
+ compatible = "amlogic,aml8726-gpio";
+ reg = <0xc110806c 4>, /* oen cbus 0x201b */
+ <0xc1108070 4>, /* out */
+ <0xc1108074 4>; /* in */
+
+ gpio-controller;
+ #gpio-cells = <1>;
+ pin-count = <32>;
+ };
+
+ mmc@c1108c20 {
+ compatible = "amlogic,aml8726-mmc";
+ reg = <0xc1108c20 32>; /* cbus 0x2308 */
+ interrupts = <0 28 1>; /* AM_IRQ0(28) */
+
+ clocks = <&clk81>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pins_sdio_b>;
+
+ mmc-voltages = "3.3";
+
+ mmc-pwr-en = <&gpio5 31 0>; /* card_8 */
+ ins-detect = <&gpio5 29 0>; /* card_6 */
+ };
+
+ rng@c1108100 {
+ compatible = "amlogic,aml8726-rng";
+ reg = <0xc1108100 8>; /* cbus 0x2040 */
+ };
+
+ usb-phy@c1108400 {
+ /* usb-a and usb-b phy */
+ compatible = "amlogic,aml8726-m3-usb-phy";
+ reg = <0xc1108400 32>; /* cbus 0x2100 */
+ };
+
+ usb@c9040000 {
+ /* usb-a */
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xc9040000 0x40000>; /* ahbbus 0x40000*/
+ interrupts = <0 30 4>; /* AM_IRQ0(30) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ usb@c90c0000 {
+ /* usb-b */
+ compatible = "synopsys,designware-hs-otg2";
+ reg = <0xc90c0000 0x40000>; /* ahbbus 0xc0000 */
+ interrupts = <0 31 4>; /* AM_IRQ0(31) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dr_mode = "host";
+ };
+
+ eth@c9410000 {
+ /* ethernet */
+ compatible = "snps,dwmac";
+ reg = <0xc9410000 0x2000>; /* ahbbus 0x410000 */
+ interrupts = <0 8 1>; /* AM_IRQ0(8) */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+
+ screen: fb@c8001324 {
+ device_type = "display";
+ compatible = "amlogic,aml8726-fb";
+ reg = <0xc8001324 12>, /* CANVAS */
+ <0xc1106800 1024>, /* VIU */
+ <0xc1107400 1024>; /* VPP */
+ interrupts = <0 2 1>, /* AM_IRQ0(2) */
+ <0 3 1>, /* AM_IRQ0(3) */
+ <0 12 1>, /* AM_IRQ0(12) */
+ <0 13 1>; /* AM_IRQ0(13) */
+
+ address = <0x84900000>; /* match memreserve */
+ width = <720>;
+ height = <480>;
+ depth = <24>;
+ linebytes = <2160>;
+ };
+ };
+
+ chosen {
+ stdin = "uart0";
+ stdout = "uart0";
+ };
+};
+
+&clk81 {
+ clock-frequency = <0>;
+};
+
+&uart_AO {
+ status = "okay";
+ current-speed = <115200>;
+};
diff --git a/sys/boot/ficl/Makefile.depend b/sys/boot/ficl/Makefile.depend
index ff32eeb23f58..ab9c549baedf 100644
--- a/sys/boot/ficl/Makefile.depend
+++ b/sys/boot/ficl/Makefile.depend
@@ -1,3 +1,4 @@
+# $FreeBSD$
# Autogenerated - do NOT edit!
DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
diff --git a/sys/boot/forth/support.4th b/sys/boot/forth/support.4th
index 367d157d0a60..08f500496d92 100644
--- a/sys/boot/forth/support.4th
+++ b/sys/boot/forth/support.4th
@@ -1437,12 +1437,12 @@ also builtins
abort" Unable to load a kernel!"
;
-: load_xen ( -- )
+: load_xen ( -- flag )
s" xen_kernel" getenv dup -1 <> if
- 1 1 load
+ 1 1 load ( c-addr/u flag N -- flag )
else
drop
- 0
+ 0 ( -1 -- flag )
then
;
diff --git a/sys/boot/i386/boot0/Makefile.depend b/sys/boot/i386/boot0/Makefile.depend
index 29fda55c252f..3af2d7f1f4d2 100644
--- a/sys/boot/i386/boot0/Makefile.depend
+++ b/sys/boot/i386/boot0/Makefile.depend
@@ -1,3 +1,4 @@
+# $FreeBSD$
# Autogenerated - do NOT edit!
DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
diff --git a/sys/boot/i386/boot0sio/Makefile.depend b/sys/boot/i386/boot0sio/Makefile.depend
index 29fda55c252f..3af2d7f1f4d2 100644
--- a/sys/boot/i386/boot0sio/Makefile.depend
+++ b/sys/boot/i386/boot0sio/Makefile.depend
@@ -1,3 +1,4 @@
+# $FreeBSD$
# Autogenerated - do NOT edit!
DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
diff --git a/sys/boot/i386/boot2/Makefile.depend b/sys/boot/i386/boot2/Makefile.depend
index 29fda55c252f..3af2d7f1f4d2 100644
--- a/sys/boot/i386/boot2/Makefile.depend
+++ b/sys/boot/i386/boot2/Makefile.depend
@@ -1,3 +1,4 @@
+# $FreeBSD$
# Autogenerated - do NOT edit!
DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
diff --git a/sys/boot/i386/loader/Makefile.depend b/sys/boot/i386/loader/Makefile.depend
index 29fda55c252f..3af2d7f1f4d2 100644
--- a/sys/boot/i386/loader/Makefile.depend
+++ b/sys/boot/i386/loader/Makefile.depend
@@ -1,3 +1,4 @@
+# $FreeBSD$
# Autogenerated - do NOT edit!
DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
diff --git a/sys/boot/i386/zfsloader/Makefile.depend b/sys/boot/i386/zfsloader/Makefile.depend
index 29fda55c252f..3af2d7f1f4d2 100644
--- a/sys/boot/i386/zfsloader/Makefile.depend
+++ b/sys/boot/i386/zfsloader/Makefile.depend
@@ -1,3 +1,4 @@
+# $FreeBSD$
# Autogenerated - do NOT edit!
DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
diff --git a/sys/boot/uboot/lib/module.c b/sys/boot/uboot/lib/module.c
index ed887b7bb74f..0951ed6618e4 100644
--- a/sys/boot/uboot/lib/module.c
+++ b/sys/boot/uboot/lib/module.c
@@ -47,8 +47,10 @@ uboot_autoload(void)
#if defined(LOADER_FDT_SUPPORT)
int err;
- if ((err = fdt_setup_fdtp()) != 0)
+ if ((err = fdt_setup_fdtp()) != 0) {
+ printf("No valid device tree blob found!\n");
return (err);
+ }
#endif
return(0);
diff --git a/sys/boot/userboot/userboot/conf.c b/sys/boot/userboot/userboot/conf.c
index 6727a223e327..b8daa7396ca3 100644
--- a/sys/boot/userboot/userboot/conf.c
+++ b/sys/boot/userboot/userboot/conf.c
@@ -65,10 +65,11 @@ struct fs_ops *file_system[] = {
&host_fsops,
&ufs_fsops,
&cd9660_fsops,
- &gzipfs_fsops,
#if defined(USERBOOT_ZFS_SUPPORT)
&zfs_fsops,
#endif
+ &gzipfs_fsops,
+ &bzipfs_fsops,
NULL
};
diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c
index 8d21c5714302..d889047ffbd5 100644
--- a/sys/boot/zfs/zfsimpl.c
+++ b/sys/boot/zfs/zfsimpl.c
@@ -1255,6 +1255,10 @@ dnode_read(const spa_t *spa, const dnode_phys_t *dnode, off_t offset, void *buf,
ibn = bn >> ((nlevels - i - 1) * ibshift);
ibn &= ((1 << ibshift) - 1);
bp = indbp[ibn];
+ if (BP_IS_HOLE(&bp)) {
+ memset(dnode_cache_buf, 0, bsize);
+ break;
+ }
rc = zio_read(spa, &bp, dnode_cache_buf);
if (rc)
return (rc);
diff --git a/sys/cam/cam.c b/sys/cam/cam.c
index 939dd76c3068..1f627ef1e63c 100644
--- a/sys/cam/cam.c
+++ b/sys/cam/cam.c
@@ -157,6 +157,56 @@ cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen)
*dst = '\0';
}
+void
+cam_strvis_sbuf(struct sbuf *sb, const u_int8_t *src, int srclen,
+ uint32_t flags)
+{
+
+ /* Trim leading/trailing spaces, nulls. */
+ while (srclen > 0 && src[0] == ' ')
+ src++, srclen--;
+ while (srclen > 0
+ && (src[srclen-1] == ' ' || src[srclen-1] == '\0'))
+ srclen--;
+
+ while (srclen > 0) {
+ if (*src < 0x20 || *src >= 0x80) {
+ /* SCSI-II Specifies that these should never occur. */
+ /* non-printable character */
+ switch (flags & CAM_STRVIS_FLAG_NONASCII_MASK) {
+ case CAM_STRVIS_FLAG_NONASCII_ESC:
+ sbuf_printf(sb, "\\%c%c%c",
+ ((*src & 0300) >> 6) + '0',
+ ((*src & 0070) >> 3) + '0',
+ ((*src & 0007) >> 0) + '0');
+ break;
+ case CAM_STRVIS_FLAG_NONASCII_RAW:
+ /*
+ * If we run into a NUL, just transform it
+ * into a space.
+ */
+ if (*src != 0x00)
+ sbuf_putc(sb, *src);
+ else
+ sbuf_putc(sb, ' ');
+ break;
+ case CAM_STRVIS_FLAG_NONASCII_SPC:
+ sbuf_putc(sb, ' ');
+ break;
+ case CAM_STRVIS_FLAG_NONASCII_TRIM:
+ default:
+ break;
+ }
+ } else {
+ /* normal character */
+ sbuf_putc(sb, *src);
+ }
+ src++;
+ srclen--;
+ }
+}
+
+
/*
* Compare string with pattern, returning 0 on match.
* Short pattern matches trailing blanks in name,
diff --git a/sys/cam/cam.h b/sys/cam/cam.h
index e08524b908ac..63f83c79d9fc 100644
--- a/sys/cam/cam.h
+++ b/sys/cam/cam.h
@@ -342,6 +342,15 @@ typedef enum {
CAM_EAF_PRINT_RESULT = 0x20
} cam_error_ata_flags;
+typedef enum {
+ CAM_STRVIS_FLAG_NONE = 0x00,
+ CAM_STRVIS_FLAG_NONASCII_MASK = 0x03,
+ CAM_STRVIS_FLAG_NONASCII_TRIM = 0x00,
+ CAM_STRVIS_FLAG_NONASCII_RAW = 0x01,
+ CAM_STRVIS_FLAG_NONASCII_SPC = 0x02,
+ CAM_STRVIS_FLAG_NONASCII_ESC = 0x03
+} cam_strvis_flags;
+
struct cam_status_entry
{
cam_status status_code;
@@ -354,6 +363,7 @@ extern const int num_cam_status_entries;
extern int cam_sort_io_queues;
#endif
union ccb;
+struct sbuf;
#ifdef SYSCTL_DECL /* from sysctl.h */
SYSCTL_DECL(_kern_cam);
@@ -366,6 +376,8 @@ caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries,
int entry_size, cam_quirkmatch_t *comp_func);
void cam_strvis(u_int8_t *dst, const u_int8_t *src, int srclen, int dstlen);
+void cam_strvis_sbuf(struct sbuf *sb, const u_int8_t *src, int srclen,
+ uint32_t flags);
int cam_strmatch(const u_int8_t *str, const u_int8_t *pattern, int str_len);
const struct cam_status_entry*
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index b2cdb71304ae..62767741f5ee 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -5011,9 +5011,9 @@ ctl_disable_lun(struct ctl_be_lun *be_lun)
lun->lun);
mtx_lock(&softc->ctl_lock);
if (retval != 0) {
- printf("ctl_alloc_lun: FETD %s port %d returned error "
+ printf("%s: FETD %s port %d returned error "
"%d for lun_disable on target %ju lun %jd\n",
- port->port_name, port->targ_port, retval,
+ __func__, port->port_name, port->targ_port, retval,
(uintmax_t)lun->target.id, (intmax_t)lun->lun);
}
}
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index ba595508bde4..74ec3df1f0cd 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -1657,16 +1657,24 @@ ctlfe_onoffline(void *arg, int online)
* down to the SIM. Otherwise, record what the SIM
* has reported.
*/
- if ((bus_softc->port.wwnn != 0)
- && (bus_softc->port.wwpn != 0)) {
+ if (bus_softc->port.wwnn != 0 && bus_softc->port.wwnn
+ != ccb->knob.xport_specific.fc.wwnn) {
ccb->knob.xport_specific.fc.wwnn =
- bus_softc->port.wwnn;
- ccb->knob.xport_specific.fc.wwpn =
- bus_softc->port.wwpn;
+ bus_softc->port.wwnn;
set_wwnn = 1;
} else {
ctl_port_set_wwns(&bus_softc->port,
true, ccb->knob.xport_specific.fc.wwnn,
+ false, 0);
+ }
+ if (bus_softc->port.wwpn != 0 && bus_softc->port.wwpn
+ != ccb->knob.xport_specific.fc.wwpn) {
+ ccb->knob.xport_specific.fc.wwpn =
+ bus_softc->port.wwpn;
+ set_wwnn = 1;
+ } else {
+ ctl_port_set_wwns(&bus_softc->port,
+ false, 0,
true, ccb->knob.xport_specific.fc.wwpn);
}
#endif /* RANDOM_WWNN */
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c
index a429259f82b7..8f27fd9c1bee 100644
--- a/sys/cam/scsi/scsi_all.c
+++ b/sys/cam/scsi/scsi_all.c
@@ -6453,6 +6453,830 @@ bailout:
return (retval);
}
+struct scsi_attrib_table_entry scsi_mam_attr_table[] = {
+ { SMA_ATTR_REM_CAP_PARTITION, SCSI_ATTR_FLAG_NONE,
+ "Remaining Capacity in Partition",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,/*parse_str*/ NULL },
+ { SMA_ATTR_MAX_CAP_PARTITION, SCSI_ATTR_FLAG_NONE,
+ "Maximum Capacity in Partition",
+ /*suffix*/"MB", /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_TAPEALERT_FLAGS, SCSI_ATTR_FLAG_HEX,
+ "TapeAlert Flags",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_LOAD_COUNT, SCSI_ATTR_FLAG_NONE,
+ "Load Count",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_MAM_SPACE_REMAINING, SCSI_ATTR_FLAG_NONE,
+ "MAM Space Remaining",
+ /*suffix*/"bytes", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_ASSIGNING_ORG, SCSI_ATTR_FLAG_NONE,
+ "Assigning Organization",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_FORMAT_DENSITY_CODE, SCSI_ATTR_FLAG_HEX,
+ "Format Density Code",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_INITIALIZATION_COUNT, SCSI_ATTR_FLAG_NONE,
+ "Initialization Count",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf, /*parse_str*/ NULL },
+ { SMA_ATTR_VOLUME_ID, SCSI_ATTR_FLAG_NONE,
+ "Volume Identifier",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_VOLUME_CHANGE_REF, SCSI_ATTR_FLAG_HEX,
+ "Volume Change Reference",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_SERIAL_LAST_LOAD, SCSI_ATTR_FLAG_NONE,
+ "Device Vendor/Serial at Last Load",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_SERIAL_LAST_LOAD_1, SCSI_ATTR_FLAG_NONE,
+ "Device Vendor/Serial at Last Load - 1",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_SERIAL_LAST_LOAD_2, SCSI_ATTR_FLAG_NONE,
+ "Device Vendor/Serial at Last Load - 2",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_DEV_SERIAL_LAST_LOAD_3, SCSI_ATTR_FLAG_NONE,
+ "Device Vendor/Serial at Last Load - 3",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_vendser_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TOTAL_MB_WRITTEN_LT, SCSI_ATTR_FLAG_NONE,
+ "Total MB Written in Medium Life",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TOTAL_MB_READ_LT, SCSI_ATTR_FLAG_NONE,
+ "Total MB Read in Medium Life",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TOTAL_MB_WRITTEN_CUR, SCSI_ATTR_FLAG_NONE,
+ "Total MB Written in Current/Last Load",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TOTAL_MB_READ_CUR, SCSI_ATTR_FLAG_NONE,
+ "Total MB Read in Current/Last Load",
+ /*suffix*/ "MB", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_FIRST_ENC_BLOCK, SCSI_ATTR_FLAG_NONE,
+ "Logical Position of First Encrypted Block",
+ /*suffix*/ NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_NEXT_UNENC_BLOCK, SCSI_ATTR_FLAG_NONE,
+ "Logical Position of First Unencrypted Block after First "
+ "Encrypted Block",
+ /*suffix*/ NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MEDIUM_USAGE_HIST, SCSI_ATTR_FLAG_NONE,
+ "Medium Usage History",
+ /*suffix*/ NULL, /*to_str*/ NULL,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_PART_USAGE_HIST, SCSI_ATTR_FLAG_NONE,
+ "Partition Usage History",
+ /*suffix*/ NULL, /*to_str*/ NULL,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_MANUF, SCSI_ATTR_FLAG_NONE,
+ "Medium Manufacturer",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_SERIAL, SCSI_ATTR_FLAG_NONE,
+ "Medium Serial Number",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_LENGTH, SCSI_ATTR_FLAG_NONE,
+ "Medium Length",
+ /*suffix*/"m", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_WIDTH, SCSI_ATTR_FLAG_FP | SCSI_ATTR_FLAG_DIV_10 |
+ SCSI_ATTR_FLAG_FP_1DIGIT,
+ "Medium Width",
+ /*suffix*/"mm", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_ASSIGNING_ORG, SCSI_ATTR_FLAG_NONE,
+ "Assigning Organization",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_DENSITY_CODE, SCSI_ATTR_FLAG_HEX,
+ "Medium Density Code",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_MANUF_DATE, SCSI_ATTR_FLAG_NONE,
+ "Medium Manufacture Date",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MAM_CAPACITY, SCSI_ATTR_FLAG_NONE,
+ "MAM Capacity",
+ /*suffix*/"bytes", /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_TYPE, SCSI_ATTR_FLAG_HEX,
+ "Medium Type",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_TYPE_INFO, SCSI_ATTR_FLAG_HEX,
+ "Medium Type Information",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MED_SERIAL_NUM, SCSI_ATTR_FLAG_NONE,
+ "Medium Serial Number",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_APP_VENDOR, SCSI_ATTR_FLAG_NONE,
+ "Application Vendor",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_APP_NAME, SCSI_ATTR_FLAG_NONE,
+ "Application Name",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_APP_VERSION, SCSI_ATTR_FLAG_NONE,
+ "Application Version",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_USER_MED_TEXT_LABEL, SCSI_ATTR_FLAG_NONE,
+ "User Medium Text Label",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_LAST_WRITTEN_TIME, SCSI_ATTR_FLAG_NONE,
+ "Date and Time Last Written",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_TEXT_LOCAL_ID, SCSI_ATTR_FLAG_HEX,
+ "Text Localization Identifier",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_BARCODE, SCSI_ATTR_FLAG_NONE,
+ "Barcode",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_HOST_OWNER_NAME, SCSI_ATTR_FLAG_NONE,
+ "Owning Host Textual Name",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_MEDIA_POOL, SCSI_ATTR_FLAG_NONE,
+ "Media Pool",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_text_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_PART_USER_LABEL, SCSI_ATTR_FLAG_NONE,
+ "Partition User Text Label",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_LOAD_UNLOAD_AT_PART, SCSI_ATTR_FLAG_NONE,
+ "Load/Unload at Partition",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_int_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_APP_FORMAT_VERSION, SCSI_ATTR_FLAG_NONE,
+ "Application Format Version",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_ascii_sbuf,
+ /*parse_str*/ NULL },
+ { SMA_ATTR_VOL_COHERENCY_INFO, SCSI_ATTR_FLAG_NONE,
+ "Volume Coherency Information",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_volcoh_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff1, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Creation",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff2, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM C3",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff3, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM RW",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff4, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM SDC List",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ff7, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Post Scan",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x0ffe, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Checksum",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f1, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Creation",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f2, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM C3",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f3, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM RW",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f4, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM SDC List",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17f7, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Post Scan",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+ { 0x17ff, SCSI_ATTR_FLAG_NONE,
+ "Spectra MLM Checksum",
+ /*suffix*/NULL, /*to_str*/ scsi_attrib_hexdump_sbuf,
+ /*parse_str*/ NULL },
+};
+
+/*
+ * Print out Volume Coherency Information (Attribute 0x080c).
+ * This field has two variable length members, including one at the
+ * beginning, so it isn't practical to have a fixed structure definition.
+ * This is current as of SSC4r03 (see section 4.2.21.3), dated March 25,
+ * 2013.
+ */
+int
+scsi_attrib_volcoh_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ size_t avail_len;
+ uint32_t field_size;
+ uint64_t tmp_val;
+ uint8_t *cur_ptr;
+ int retval;
+ int vcr_len, as_len;
+
+ retval = 0;
+ tmp_val = 0;
+
+ field_size = scsi_2btoul(hdr->length);
+ avail_len = valid_len - sizeof(*hdr);
+ if (field_size > avail_len) {
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ field_size);
+ }
+ retval = 1;
+ goto bailout;
+ } else if (field_size == 0) {
+ /*
+ * It isn't clear from the spec whether a field length of
+ * 0 is invalid here. It probably is, but be lenient here
+ * to avoid inconveniencing the user.
+ */
+ goto bailout;
+ }
+ cur_ptr = hdr->attribute;
+ vcr_len = *cur_ptr;
+ cur_ptr++;
+
+ sbuf_printf(sb, "\n\tVolume Change Reference Value:");
+
+ switch (vcr_len) {
+ case 0:
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Volume Change "
+ "Reference value has length of 0");
+ }
+ retval = 1;
+ goto bailout;
+ break; /*NOTREACHED*/
+ case 1:
+ tmp_val = *cur_ptr;
+ break;
+ case 2:
+ tmp_val = scsi_2btoul(cur_ptr);
+ break;
+ case 3:
+ tmp_val = scsi_3btoul(cur_ptr);
+ break;
+ case 4:
+ tmp_val = scsi_4btoul(cur_ptr);
+ break;
+ case 8:
+ tmp_val = scsi_8btou64(cur_ptr);
+ break;
+ default:
+ sbuf_printf(sb, "\n");
+ sbuf_hexdump(sb, cur_ptr, vcr_len, NULL, 0);
+ break;
+ }
+ if (vcr_len <= 8)
+ sbuf_printf(sb, " 0x%jx\n", (uintmax_t)tmp_val);
+
+ cur_ptr += vcr_len;
+ tmp_val = scsi_8btou64(cur_ptr);
+ sbuf_printf(sb, "\tVolume Coherency Count: %ju\n", (uintmax_t)tmp_val);
+
+ cur_ptr += sizeof(tmp_val);
+ tmp_val = scsi_8btou64(cur_ptr);
+ sbuf_printf(sb, "\tVolume Coherency Set Identifier: 0x%jx\n",
+ (uintmax_t)tmp_val);
+
+ /*
+ * Figure out how long the Application Client Specific Information
+ * is and produce a hexdump.
+ */
+ cur_ptr += sizeof(tmp_val);
+ as_len = scsi_2btoul(cur_ptr);
+ cur_ptr += sizeof(uint16_t);
+ sbuf_printf(sb, "\tApplication Client Specific Information: ");
+ if (((as_len == SCSI_LTFS_VER0_LEN)
+ || (as_len == SCSI_LTFS_VER1_LEN))
+ && (strncmp(cur_ptr, SCSI_LTFS_STR_NAME, SCSI_LTFS_STR_LEN) == 0)) {
+ sbuf_printf(sb, "LTFS\n");
+ cur_ptr += SCSI_LTFS_STR_LEN + 1;
+ if (cur_ptr[SCSI_LTFS_UUID_LEN] != '\0')
+ cur_ptr[SCSI_LTFS_UUID_LEN] = '\0';
+ sbuf_printf(sb, "\tLTFS UUID: %s\n", cur_ptr);
+ cur_ptr += SCSI_LTFS_UUID_LEN + 1;
+ /* XXX KDM check the length */
+ sbuf_printf(sb, "\tLTFS Version: %d\n", *cur_ptr);
+ } else {
+ sbuf_printf(sb, "Unknown\n");
+ sbuf_hexdump(sb, cur_ptr, as_len, NULL, 0);
+ }
+
+bailout:
+ return (retval);
+}
+
+int
+scsi_attrib_vendser_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ size_t avail_len;
+ uint32_t field_size;
+ struct scsi_attrib_vendser *vendser;
+ cam_strvis_flags strvis_flags;
+ int retval = 0;
+
+ field_size = scsi_2btoul(hdr->length);
+ avail_len = valid_len - sizeof(*hdr);
+ if (field_size > avail_len) {
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ field_size);
+ }
+ retval = 1;
+ goto bailout;
+ } else if (field_size == 0) {
+ /*
+ * A field size of 0 doesn't make sense here. The device
+ * can at least give you the vendor ID, even if it can't
+ * give you the serial number.
+ */
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "The length of "
+ "attribute ID 0x%.4x is 0",
+ scsi_2btoul(hdr->id));
+ }
+ retval = 1;
+ goto bailout;
+ }
+ vendser = (struct scsi_attrib_vendser *)hdr->attribute;
+
+ switch (output_flags & SCSI_ATTR_OUTPUT_NONASCII_MASK) {
+ case SCSI_ATTR_OUTPUT_NONASCII_TRIM:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_TRIM;
+ break;
+ case SCSI_ATTR_OUTPUT_NONASCII_RAW:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_RAW;
+ break;
+ case SCSI_ATTR_OUTPUT_NONASCII_ESC:
+ default:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_ESC;
+ break;;
+ }
+ cam_strvis_sbuf(sb, vendser->vendor, sizeof(vendser->vendor),
+ strvis_flags);
+ sbuf_putc(sb, ' ');
+ cam_strvis_sbuf(sb, vendser->serial_num, sizeof(vendser->serial_num),
+ strvis_flags);
+bailout:
+ return (retval);
+}
+
+int
+scsi_attrib_hexdump_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ uint32_t field_size;
+ ssize_t avail_len;
+ uint32_t print_len;
+ uint8_t *num_ptr;
+ int retval = 0;
+
+ field_size = scsi_2btoul(hdr->length);
+ avail_len = valid_len - sizeof(*hdr);
+ print_len = MIN(avail_len, field_size);
+ num_ptr = hdr->attribute;
+
+ if (print_len > 0) {
+ sbuf_printf(sb, "\n");
+ sbuf_hexdump(sb, num_ptr, print_len, NULL, 0);
+ }
+
+ return (retval);
+}
+
+int
+scsi_attrib_int_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ uint64_t print_number;
+ size_t avail_len;
+ uint32_t number_size;
+ int retval = 0;
+
+ number_size = scsi_2btoul(hdr->length);
+
+ avail_len = valid_len - sizeof(*hdr);
+ if (avail_len < number_size) {
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ number_size);
+ }
+ retval = 1;
+ goto bailout;
+ }
+
+ switch (number_size) {
+ case 0:
+ /*
+ * We don't treat this as an error, since there may be
+ * scenarios where a device reports a field but then gives
+ * a length of 0. See the note in scsi_attrib_ascii_sbuf().
+ */
+ goto bailout;
+ break; /*NOTREACHED*/
+ case 1:
+ print_number = hdr->attribute[0];
+ break;
+ case 2:
+ print_number = scsi_2btoul(hdr->attribute);
+ break;
+ case 3:
+ print_number = scsi_3btoul(hdr->attribute);
+ break;
+ case 4:
+ print_number = scsi_4btoul(hdr->attribute);
+ break;
+ case 8:
+ print_number = scsi_8btou64(hdr->attribute);
+ break;
+ default:
+ /*
+ * If we wind up here, the number is too big to print
+ * normally, so just do a hexdump.
+ */
+ retval = scsi_attrib_hexdump_sbuf(sb, hdr, valid_len,
+ flags, output_flags,
+ error_str, error_str_len);
+ goto bailout;
+ break;
+ }
+
+ if (flags & SCSI_ATTR_FLAG_FP) {
+#ifndef _KERNEL
+ long double num_float;
+
+ num_float = (long double)print_number;
+
+ if (flags & SCSI_ATTR_FLAG_DIV_10)
+ num_float /= 10;
+
+ sbuf_printf(sb, "%.*Lf", (flags & SCSI_ATTR_FLAG_FP_1DIGIT) ?
+ 1 : 0, num_float);
+#else /* _KERNEL */
+ sbuf_printf(sb, "%ju", (flags & SCSI_ATTR_FLAG_DIV_10) ?
+ (print_number / 10) : print_number);
+#endif /* _KERNEL */
+ } else if (flags & SCSI_ATTR_FLAG_HEX) {
+ sbuf_printf(sb, "0x%jx", (uintmax_t)print_number);
+ } else
+ sbuf_printf(sb, "%ju", (uintmax_t)print_number);
+
+bailout:
+ return (retval);
+}
+
+int
+scsi_attrib_ascii_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ size_t avail_len;
+ uint32_t field_size, print_size;
+ int retval = 0;
+
+ avail_len = valid_len - sizeof(*hdr);
+ field_size = scsi_2btoul(hdr->length);
+ print_size = MIN(avail_len, field_size);
+
+ if (print_size > 0) {
+ cam_strvis_flags strvis_flags;
+
+ switch (output_flags & SCSI_ATTR_OUTPUT_NONASCII_MASK) {
+ case SCSI_ATTR_OUTPUT_NONASCII_TRIM:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_TRIM;
+ break;
+ case SCSI_ATTR_OUTPUT_NONASCII_RAW:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_RAW;
+ break;
+ case SCSI_ATTR_OUTPUT_NONASCII_ESC:
+ default:
+ strvis_flags = CAM_STRVIS_FLAG_NONASCII_ESC;
+ break;
+ }
+ cam_strvis_sbuf(sb, hdr->attribute, print_size, strvis_flags);
+ } else if (avail_len < field_size) {
+ /*
+ * We only report an error if the user didn't allocate
+ * enough space to hold the full value of this field. If
+ * the field length is 0, that is allowed by the spec.
+ * e.g. in SPC-4r37, section 7.4.2.2.5, VOLUME IDENTIFIER
+ * "This attribute indicates the current volume identifier
+ * (see SMC-3) of the medium. If the device server supports
+ * this attribute but does not have access to the volume
+ * identifier, the device server shall report this attribute
+ * with an attribute length value of zero."
+ */
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ field_size);
+ }
+ retval = 1;
+ }
+
+ return (retval);
+}
+
+int
+scsi_attrib_text_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len)
+{
+ size_t avail_len;
+ uint32_t field_size, print_size;
+ int retval = 0;
+ int esc_text = 1;
+
+ avail_len = valid_len - sizeof(*hdr);
+ field_size = scsi_2btoul(hdr->length);
+ print_size = MIN(avail_len, field_size);
+
+ if ((output_flags & SCSI_ATTR_OUTPUT_TEXT_MASK) ==
+ SCSI_ATTR_OUTPUT_TEXT_RAW)
+ esc_text = 0;
+
+ if (print_size > 0) {
+ uint32_t i;
+
+ for (i = 0; i < print_size; i++) {
+ if (hdr->attribute[i] == '\0')
+ continue;
+ else if (((unsigned char)hdr->attribute[i] < 0x80)
+ || (esc_text == 0))
+ sbuf_putc(sb, hdr->attribute[i]);
+ else
+ sbuf_printf(sb, "%%%02x",
+ (unsigned char)hdr->attribute[i]);
+ }
+ } else if (avail_len < field_size) {
+ /*
+ * We only report an error if the user didn't allocate
+ * enough space to hold the full value of this field.
+ */
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Available "
+ "length of attribute ID 0x%.4x %zu < field "
+ "length %u", scsi_2btoul(hdr->id), avail_len,
+ field_size);
+ }
+ retval = 1;
+ }
+
+ return (retval);
+}
+
+struct scsi_attrib_table_entry *
+scsi_find_attrib_entry(struct scsi_attrib_table_entry *table,
+ size_t num_table_entries, uint32_t id)
+{
+ uint32_t i;
+
+ for (i = 0; i < num_table_entries; i++) {
+ if (table[i].id == id)
+ return (&table[i]);
+ }
+
+ return (NULL);
+}
+
+struct scsi_attrib_table_entry *
+scsi_get_attrib_entry(uint32_t id)
+{
+ return (scsi_find_attrib_entry(scsi_mam_attr_table,
+ sizeof(scsi_mam_attr_table) / sizeof(scsi_mam_attr_table[0]),
+ id));
+}
+
+int
+scsi_attrib_value_sbuf(struct sbuf *sb, uint32_t valid_len,
+ struct scsi_mam_attribute_header *hdr, uint32_t output_flags,
+ char *error_str, size_t error_str_len)
+{
+ int retval;
+
+ switch (hdr->byte2 & SMA_FORMAT_MASK) {
+ case SMA_FORMAT_ASCII:
+ retval = scsi_attrib_ascii_sbuf(sb, hdr, valid_len,
+ SCSI_ATTR_FLAG_NONE, output_flags, error_str,error_str_len);
+ break;
+ case SMA_FORMAT_BINARY:
+ if (scsi_2btoul(hdr->length) <= 8)
+ retval = scsi_attrib_int_sbuf(sb, hdr, valid_len,
+ SCSI_ATTR_FLAG_NONE, output_flags, error_str,
+ error_str_len);
+ else
+ retval = scsi_attrib_hexdump_sbuf(sb, hdr, valid_len,
+ SCSI_ATTR_FLAG_NONE, output_flags, error_str,
+ error_str_len);
+ break;
+ case SMA_FORMAT_TEXT:
+ retval = scsi_attrib_text_sbuf(sb, hdr, valid_len,
+ SCSI_ATTR_FLAG_NONE, output_flags, error_str,
+ error_str_len);
+ break;
+ default:
+ if (error_str != NULL) {
+ snprintf(error_str, error_str_len, "Unknown attribute "
+ "format 0x%x", hdr->byte2 & SMA_FORMAT_MASK);
+ }
+ retval = 1;
+ goto bailout;
+ break; /*NOTREACHED*/
+ }
+
+ sbuf_trim(sb);
+
+bailout:
+
+ return (retval);
+}
+
+void
+scsi_attrib_prefix_sbuf(struct sbuf *sb, uint32_t output_flags,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, const char *desc)
+{
+ int need_space = 0;
+ uint32_t len;
+ uint32_t id;
+
+ /*
+ * We can't do anything if we don't have enough valid data for the
+ * header.
+ */
+ if (valid_len < sizeof(*hdr))
+ return;
+
+ id = scsi_2btoul(hdr->id);
+ /*
+ * Note that we print out the value of the attribute listed in the
+ * header, regardless of whether we actually got that many bytes
+ * back from the device through the controller. A truncated result
+ * could be the result of a failure to ask for enough data; the
+ * header indicates how many bytes are allocated for this attribute
+ * in the MAM.
+ */
+ len = scsi_2btoul(hdr->length);
+
+ if ((output_flags & SCSI_ATTR_OUTPUT_FIELD_MASK) ==
+ SCSI_ATTR_OUTPUT_FIELD_NONE)
+ return;
+
+ if ((output_flags & SCSI_ATTR_OUTPUT_FIELD_DESC)
+ && (desc != NULL)) {
+ sbuf_printf(sb, "%s", desc);
+ need_space = 1;
+ }
+
+ if (output_flags & SCSI_ATTR_OUTPUT_FIELD_NUM) {
+ sbuf_printf(sb, "%s(0x%.4x)", (need_space) ? " " : "", id);
+ need_space = 0;
+ }
+
+ if (output_flags & SCSI_ATTR_OUTPUT_FIELD_SIZE) {
+ sbuf_printf(sb, "%s[%d]", (need_space) ? " " : "", len);
+ need_space = 0;
+ }
+ if (output_flags & SCSI_ATTR_OUTPUT_FIELD_RW) {
+ sbuf_printf(sb, "%s(%s)", (need_space) ? " " : "",
+ (hdr->byte2 & SMA_READ_ONLY) ? "RO" : "RW");
+ }
+ sbuf_printf(sb, ": ");
+}
+
+int
+scsi_attrib_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, struct scsi_attrib_table_entry *user_table,
+ size_t num_user_entries, int prefer_user_table,
+ uint32_t output_flags, char *error_str, int error_str_len)
+{
+ int retval;
+ struct scsi_attrib_table_entry *table1 = NULL, *table2 = NULL;
+ struct scsi_attrib_table_entry *entry = NULL;
+ size_t table1_size = 0, table2_size = 0;
+ uint32_t id;
+
+ retval = 0;
+
+ if (valid_len < sizeof(*hdr)) {
+ retval = 1;
+ goto bailout;
+ }
+
+ id = scsi_2btoul(hdr->id);
+
+ if (user_table != NULL) {
+ if (prefer_user_table != 0) {
+ table1 = user_table;
+ table1_size = num_user_entries;
+ table2 = scsi_mam_attr_table;
+ table2_size = sizeof(scsi_mam_attr_table) /
+ sizeof(scsi_mam_attr_table[0]);
+ } else {
+ table1 = scsi_mam_attr_table;
+ table1_size = sizeof(scsi_mam_attr_table) /
+ sizeof(scsi_mam_attr_table[0]);
+ table2 = user_table;
+ table2_size = num_user_entries;
+ }
+ } else {
+ table1 = scsi_mam_attr_table;
+ table1_size = sizeof(scsi_mam_attr_table) /
+ sizeof(scsi_mam_attr_table[0]);
+ }
+
+ entry = scsi_find_attrib_entry(table1, table1_size, id);
+ if (entry != NULL) {
+ scsi_attrib_prefix_sbuf(sb, output_flags, hdr, valid_len,
+ entry->desc);
+ if (entry->to_str == NULL)
+ goto print_default;
+ retval = entry->to_str(sb, hdr, valid_len, entry->flags,
+ output_flags, error_str, error_str_len);
+ goto bailout;
+ }
+ if (table2 != NULL) {
+ entry = scsi_find_attrib_entry(table2, table2_size, id);
+ if (entry != NULL) {
+ if (entry->to_str == NULL)
+ goto print_default;
+
+ scsi_attrib_prefix_sbuf(sb, output_flags, hdr,
+ valid_len, entry->desc);
+ retval = entry->to_str(sb, hdr, valid_len, entry->flags,
+ output_flags, error_str,
+ error_str_len);
+ goto bailout;
+ }
+ }
+
+ scsi_attrib_prefix_sbuf(sb, output_flags, hdr, valid_len, NULL);
+
+print_default:
+ retval = scsi_attrib_value_sbuf(sb, valid_len, hdr, output_flags,
+ error_str, error_str_len);
+bailout:
+ if (retval == 0) {
+ if ((entry != NULL)
+ && (entry->suffix != NULL))
+ sbuf_printf(sb, " %s", entry->suffix);
+
+ sbuf_trim(sb);
+ sbuf_printf(sb, "\n");
+ }
+
+ return (retval);
+}
+
void
scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
@@ -7403,6 +8227,74 @@ scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
timeout);
}
+void
+scsi_read_attribute(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int8_t service_action,
+ uint32_t element, u_int8_t elem_type, int logical_volume,
+ int partition, u_int32_t first_attribute, int cache,
+ u_int8_t *data_ptr, u_int32_t length, int sense_len,
+ u_int32_t timeout)
+{
+ struct scsi_read_attribute *scsi_cmd;
+
+ scsi_cmd = (struct scsi_read_attribute *)&csio->cdb_io.cdb_bytes;
+ bzero(scsi_cmd, sizeof(*scsi_cmd));
+
+ scsi_cmd->opcode = READ_ATTRIBUTE;
+ scsi_cmd->service_action = service_action,
+ scsi_ulto2b(element, scsi_cmd->element);
+ scsi_cmd->elem_type = elem_type;
+ scsi_cmd->logical_volume = logical_volume;
+ scsi_cmd->partition = partition;
+ scsi_ulto2b(first_attribute, scsi_cmd->first_attribute);
+ scsi_ulto4b(length, scsi_cmd->length);
+ if (cache != 0)
+ scsi_cmd->cache |= SRA_CACHE;
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ /*data_ptr*/data_ptr,
+ /*dxfer_len*/length,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+}
+
+void
+scsi_write_attribute(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, uint32_t element, int logical_volume,
+ int partition, int wtc, u_int8_t *data_ptr,
+ u_int32_t length, int sense_len, u_int32_t timeout)
+{
+ struct scsi_write_attribute *scsi_cmd;
+
+ scsi_cmd = (struct scsi_write_attribute *)&csio->cdb_io.cdb_bytes;
+ bzero(scsi_cmd, sizeof(*scsi_cmd));
+
+ scsi_cmd->opcode = WRITE_ATTRIBUTE;
+ if (wtc != 0)
+ scsi_cmd->byte2 = SWA_WTC;
+ scsi_ulto3b(element, scsi_cmd->element);
+ scsi_cmd->logical_volume = logical_volume;
+ scsi_cmd->partition = partition;
+ scsi_ulto4b(length, scsi_cmd->length);
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_OUT,
+ tag_action,
+ /*data_ptr*/data_ptr,
+ /*dxfer_len*/length,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+}
void
scsi_persistent_reserve_in(struct ccb_scsiio *csio, uint32_t retries,
diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h
index f70b09423e05..e446f6c76214 100644
--- a/sys/cam/scsi/scsi_all.h
+++ b/sys/cam/scsi/scsi_all.h
@@ -996,6 +996,216 @@ struct scsi_write_buffer
u_int8_t control;
};
+struct scsi_read_attribute
+{
+ u_int8_t opcode;
+ u_int8_t service_action;
+#define SRA_SA_ATTR_VALUES 0x00
+#define SRA_SA_ATTR_LIST 0x01
+#define SRA_SA_LOG_VOL_LIST 0x02
+#define SRA_SA_PART_LIST 0x03
+#define SRA_SA_RESTRICTED 0x04
+#define SRA_SA_SUPPORTED_ATTRS 0x05
+#define SRA_SA_MASK 0x1f
+ u_int8_t element[2];
+ u_int8_t elem_type;
+ u_int8_t logical_volume;
+ u_int8_t reserved1;
+ u_int8_t partition;
+ u_int8_t first_attribute[2];
+ u_int8_t length[4];
+ u_int8_t cache;
+#define SRA_CACHE 0x01
+ u_int8_t control;
+};
+
+struct scsi_write_attribute
+{
+ u_int8_t opcode;
+ u_int8_t byte2;
+#define SWA_WTC 0x01
+ u_int8_t element[3];
+ u_int8_t logical_volume;
+ u_int8_t reserved1;
+ u_int8_t partition;
+ u_int8_t reserved2[2];
+ u_int8_t length[4];
+ u_int8_t reserved3;
+ u_int8_t control;
+};
+
+
+struct scsi_read_attribute_values
+{
+ u_int8_t length[4];
+ u_int8_t attribute_0[0];
+};
+
+struct scsi_mam_attribute_header
+{
+ u_int8_t id[2];
+ /*
+ * Attributes obtained from SPC-4r36g (section 7.4.2.2) and
+ * SSC-4r03 (section 4.2.21).
+ */
+#define SMA_ATTR_ID_DEVICE_MIN 0x0000
+
+#define SMA_ATTR_REM_CAP_PARTITION 0x0000
+#define SMA_ATTR_MAX_CAP_PARTITION 0x0001
+#define SMA_ATTR_TAPEALERT_FLAGS 0x0002
+#define SMA_ATTR_LOAD_COUNT 0x0003
+#define SMA_ATTR_MAM_SPACE_REMAINING 0x0004
+
+#define SMA_ATTR_DEV_ASSIGNING_ORG 0x0005
+#define SMA_ATTR_FORMAT_DENSITY_CODE 0x0006
+#define SMA_ATTR_INITIALIZATION_COUNT 0x0007
+#define SMA_ATTR_VOLUME_ID 0x0008
+#define SMA_ATTR_VOLUME_CHANGE_REF 0x0009
+
+#define SMA_ATTR_DEV_SERIAL_LAST_LOAD 0x020a
+#define SMA_ATTR_DEV_SERIAL_LAST_LOAD_1 0x020b
+#define SMA_ATTR_DEV_SERIAL_LAST_LOAD_2 0x020c
+#define SMA_ATTR_DEV_SERIAL_LAST_LOAD_3 0x020d
+
+#define SMA_ATTR_TOTAL_MB_WRITTEN_LT 0x0220
+#define SMA_ATTR_TOTAL_MB_READ_LT 0x0221
+#define SMA_ATTR_TOTAL_MB_WRITTEN_CUR 0x0222
+#define SMA_ATTR_TOTAL_MB_READ_CUR 0x0223
+#define SMA_ATTR_FIRST_ENC_BLOCK 0x0224
+#define SMA_ATTR_NEXT_UNENC_BLOCK 0x0225
+
+#define SMA_ATTR_MEDIUM_USAGE_HIST 0x0340
+#define SMA_ATTR_PART_USAGE_HIST 0x0341
+
+#define SMA_ATTR_ID_DEVICE_MAX 0x03ff
+
+#define SMA_ATTR_ID_MEDIUM_MIN 0x0400
+
+#define SMA_ATTR_MED_MANUF 0x0400
+#define SMA_ATTR_MED_SERIAL 0x0401
+
+#define SMA_ATTR_MED_LENGTH 0x0402
+#define SMA_ATTR_MED_WIDTH 0x0403
+#define SMA_ATTR_MED_ASSIGNING_ORG 0x0404
+#define SMA_ATTR_MED_DENSITY_CODE 0x0405
+
+#define SMA_ATTR_MED_MANUF_DATE 0x0406
+#define SMA_ATTR_MAM_CAPACITY 0x0407
+#define SMA_ATTR_MED_TYPE 0x0408
+#define SMA_ATTR_MED_TYPE_INFO 0x0409
+#define SMA_ATTR_MED_SERIAL_NUM 0x040a
+
+#define SMA_ATTR_ID_MEDIUM_MAX 0x07ff
+
+#define SMA_ATTR_ID_HOST_MIN 0x0800
+
+#define SMA_ATTR_APP_VENDOR 0x0800
+#define SMA_ATTR_APP_NAME 0x0801
+#define SMA_ATTR_APP_VERSION 0x0802
+#define SMA_ATTR_USER_MED_TEXT_LABEL 0x0803
+#define SMA_ATTR_LAST_WRITTEN_TIME 0x0804
+#define SMA_ATTR_TEXT_LOCAL_ID 0x0805
+#define SMA_ATTR_BARCODE 0x0806
+#define SMA_ATTR_HOST_OWNER_NAME 0x0807
+#define SMA_ATTR_MEDIA_POOL 0x0808
+#define SMA_ATTR_PART_USER_LABEL 0x0809
+#define SMA_ATTR_LOAD_UNLOAD_AT_PART 0x080a
+#define SMA_ATTR_APP_FORMAT_VERSION 0x080b
+#define SMA_ATTR_VOL_COHERENCY_INFO 0x080c
+
+#define SMA_ATTR_ID_HOST_MAX 0x0bff
+
+#define SMA_ATTR_VENDOR_DEVICE_MIN 0x0c00
+#define SMA_ATTR_VENDOR_DEVICE_MAX 0x0fff
+#define SMA_ATTR_VENDOR_MEDIUM_MIN 0x1000
+#define SMA_ATTR_VENDOR_MEDIUM_MAX 0x13ff
+#define SMA_ATTR_VENDOR_HOST_MIN 0x1400
+#define SMA_ATTR_VENDOR_HOST_MAX 0x17ff
+ u_int8_t byte2;
+#define SMA_FORMAT_BINARY 0x00
+#define SMA_FORMAT_ASCII 0x01
+#define SMA_FORMAT_TEXT 0x02
+#define SMA_FORMAT_MASK 0x03
+#define SMA_READ_ONLY 0x80
+ u_int8_t length[2];
+ u_int8_t attribute[0];
+};
+
+struct scsi_attrib_list_header {
+ u_int8_t length[4];
+ u_int8_t first_attr_0[0];
+};
+
+struct scsi_attrib_lv_list {
+ u_int8_t length[2];
+ u_int8_t first_lv_number;
+ u_int8_t num_logical_volumes;
+};
+
+struct scsi_attrib_vendser {
+ uint8_t vendor[8];
+ uint8_t serial_num[32];
+};
+
+/*
+ * These values are used to decode the Volume Coherency Information
+ * Attribute (0x080c) for LTFS-format coherency information.
+ * Although the Application Client Specific lengths are different for
+ * Version 0 and Version 1, the data is in fact the same. The length
+ * difference was due to a code bug.
+ */
+#define SCSI_LTFS_VER0_LEN 42
+#define SCSI_LTFS_VER1_LEN 43
+#define SCSI_LTFS_UUID_LEN 36
+#define SCSI_LTFS_STR_NAME "LTFS"
+#define SCSI_LTFS_STR_LEN 4
+
+typedef enum {
+ SCSI_ATTR_FLAG_NONE = 0x00,
+ SCSI_ATTR_FLAG_HEX = 0x01,
+ SCSI_ATTR_FLAG_FP = 0x02,
+ SCSI_ATTR_FLAG_DIV_10 = 0x04,
+ SCSI_ATTR_FLAG_FP_1DIGIT = 0x08
+} scsi_attrib_flags;
+
+typedef enum {
+ SCSI_ATTR_OUTPUT_NONE = 0x00,
+ SCSI_ATTR_OUTPUT_TEXT_MASK = 0x03,
+ SCSI_ATTR_OUTPUT_TEXT_RAW = 0x00,
+ SCSI_ATTR_OUTPUT_TEXT_ESC = 0x01,
+ SCSI_ATTR_OUTPUT_TEXT_RSV1 = 0x02,
+ SCSI_ATTR_OUTPUT_TEXT_RSV2 = 0x03,
+ SCSI_ATTR_OUTPUT_NONASCII_MASK = 0x0c,
+ SCSI_ATTR_OUTPUT_NONASCII_TRIM = 0x00,
+ SCSI_ATTR_OUTPUT_NONASCII_ESC = 0x04,
+ SCSI_ATTR_OUTPUT_NONASCII_RAW = 0x08,
+ SCSI_ATTR_OUTPUT_NONASCII_RSV1 = 0x0c,
+ SCSI_ATTR_OUTPUT_FIELD_MASK = 0xf0,
+ SCSI_ATTR_OUTPUT_FIELD_ALL = 0xf0,
+ SCSI_ATTR_OUTPUT_FIELD_NONE = 0x00,
+ SCSI_ATTR_OUTPUT_FIELD_DESC = 0x10,
+ SCSI_ATTR_OUTPUT_FIELD_NUM = 0x20,
+ SCSI_ATTR_OUTPUT_FIELD_SIZE = 0x40,
+ SCSI_ATTR_OUTPUT_FIELD_RW = 0x80
+} scsi_attrib_output_flags;
+
+struct sbuf;
+
+struct scsi_attrib_table_entry
+{
+ u_int32_t id;
+ u_int32_t flags;
+ const char *desc;
+ const char *suffix;
+ int (*to_str)(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+ int (*parse_str)(char *str, struct scsi_mam_attribute_header *hdr,
+ uint32_t alloc_len, uint32_t flags, char *error_str,
+ int error_str_len);
+};
+
struct scsi_rw_6
{
u_int8_t opcode;
@@ -1750,6 +1960,8 @@ struct ata_pass_16 {
#define READ_16 0x88
#define COMPARE_AND_WRITE 0x89
#define WRITE_16 0x8A
+#define READ_ATTRIBUTE 0x8C
+#define WRITE_ATTRIBUTE 0x8D
#define WRITE_VERIFY_16 0x8E
#define VERIFY_16 0x8F
#define SYNCHRONIZE_CACHE_16 0x91
@@ -3272,8 +3484,6 @@ struct cam_device;
extern const char *scsi_sense_key_text[];
-struct sbuf;
-
__BEGIN_DECLS
void scsi_sense_desc(int sense_key, int asc, int ascq,
struct scsi_inquiry_data *inq_data,
@@ -3465,6 +3675,63 @@ int scsi_parse_transportid(char *transportid_str,
#endif
char *error_str, int error_str_len);
+
+int scsi_attrib_volcoh_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_vendser_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_hexdump_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_int_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_ascii_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+int scsi_attrib_text_sbuf(struct sbuf *sb,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, uint32_t flags,
+ uint32_t output_flags, char *error_str,
+ int error_str_len);
+
+struct scsi_attrib_table_entry *scsi_find_attrib_entry(
+ struct scsi_attrib_table_entry *table,
+ size_t num_table_entries, uint32_t id);
+
+struct scsi_attrib_table_entry *scsi_get_attrib_entry(uint32_t id);
+
+int scsi_attrib_value_sbuf(struct sbuf *sb, uint32_t valid_len,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t output_flags, char *error_str,
+ size_t error_str_len);
+
+void scsi_attrib_prefix_sbuf(struct sbuf *sb, uint32_t output_flags,
+ struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len, const char *desc);
+
+int scsi_attrib_sbuf(struct sbuf *sb, struct scsi_mam_attribute_header *hdr,
+ uint32_t valid_len,
+ struct scsi_attrib_table_entry *user_table,
+ size_t num_user_entries, int prefer_user_table,
+ uint32_t output_flags, char *error_str, int error_str_len);
+
void scsi_test_unit_ready(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *,
union ccb *),
@@ -3659,6 +3926,18 @@ void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int start, int load_eject,
int immediate, u_int8_t sense_len, u_int32_t timeout);
+void scsi_read_attribute(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, u_int8_t service_action,
+ uint32_t element, u_int8_t elem_type,
+ int logical_volume, int partition,
+ u_int32_t first_attribute, int cache, u_int8_t *data_ptr,
+ u_int32_t length, int sense_len, u_int32_t timeout);
+void scsi_write_attribute(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ u_int8_t tag_action, uint32_t element,
+ int logical_volume, int partition, int wtc, u_int8_t *data_ptr,
+ u_int32_t length, int sense_len, u_int32_t timeout);
void scsi_security_protocol_in(struct ccb_scsiio *csio, uint32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
diff --git a/sys/cddl/compat/opensolaris/sys/nvpair.h b/sys/cddl/compat/opensolaris/sys/nvpair.h
index fcb0c87a3d84..c90ab70d0df2 100644
--- a/sys/cddl/compat/opensolaris/sys/nvpair.h
+++ b/sys/cddl/compat/opensolaris/sys/nvpair.h
@@ -29,6 +29,8 @@
#ifndef _OPENSOLARIS_SYS_NVPAIR_H_
#define _OPENSOLARIS_SYS_NVPAIR_H_
+#ifdef _KERNEL
+
/*
* Some of the symbols in the Illumos nvpair library conflict with symbols
* provided by nv(9), so we use this preprocessor hack to avoid the conflict.
@@ -254,6 +256,8 @@
#define nvpair_unpack illumos_nvpair_unpack
#define nvpair_unpack_descriptor illumos_nvpair_unpack_descriptor
+#endif /* _KERNEL */
+
#include_next <sys/nvpair.h>
#endif
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
index a0c13777deeb..fd6e80051db8 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c
@@ -855,6 +855,10 @@ dmu_send_estimate(dsl_dataset_t *ds, dsl_dataset_t *fromds, uint64_t *sizep)
if (!dsl_dataset_is_snapshot(ds))
return (SET_ERROR(EINVAL));
+ /* fromsnap, if provided, must be a snapshot */
+ if (fromds != NULL && !dsl_dataset_is_snapshot(fromds))
+ return (SET_ERROR(EINVAL));
+
/*
* fromsnap must be an earlier snapshot from the same fs as tosnap,
* or the origin's fs.
@@ -983,10 +987,12 @@ recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
dsl_dataset_rele(snap, FTAG);
} else {
- /* if full, most recent snapshot must be $ORIGIN */
- if (dsl_dataset_phys(ds)->ds_prev_snap_txg >= TXG_INITIAL)
- return (SET_ERROR(ENODEV));
- drba->drba_snapobj = dsl_dataset_phys(ds)->ds_prev_snap_obj;
+ /* if full, then must be forced */
+ if (!drba->drba_cookie->drc_force)
+ return (SET_ERROR(EEXIST));
+ /* start from $ORIGIN@$ORIGIN, if supported */
+ drba->drba_snapobj = dp->dp_origin_snap != NULL ?
+ dp->dp_origin_snap->ds_object : 0;
}
return (0);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
index 58db4ddb71c2..7319c76e9f23 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -2161,12 +2161,14 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx)
int err;
uint64_t unused;
uint64_t ss_mv_cnt;
+ size_t max_snap_len;
err = promote_hold(ddpa, dp, FTAG);
if (err != 0)
return (err);
hds = ddpa->ddpa_clone;
+ max_snap_len = MAXNAMELEN - strlen(ddpa->ddpa_clonename) - 1;
if (dsl_dataset_phys(hds)->ds_flags & DS_FLAG_NOPROMOTE) {
promote_rele(ddpa, FTAG);
@@ -2230,6 +2232,10 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx)
/* Check that the snapshot name does not conflict */
VERIFY0(dsl_dataset_get_snapname(ds));
+ if (strlen(ds->ds_snapname) >= max_snap_len) {
+ err = SET_ERROR(ENAMETOOLONG);
+ goto out;
+ }
err = dsl_dataset_snap_lookup(hds, ds->ds_snapname, &val);
if (err == 0) {
(void) strcpy(ddpa->err_ds, snap->ds->ds_snapname);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
index 8700f4c35eba..7c89454e4fc7 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
@@ -2256,6 +2256,8 @@ spa_load_impl(spa_t *spa, uint64_t pool_guid, nvlist_t *config,
return (error);
ASSERT(spa->spa_root_vdev == rvd);
+ ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
+ ASSERT3U(spa->spa_max_ashift, <=, SPA_MAXBLOCKSHIFT);
if (type != SPA_IMPORT_ASSEMBLE) {
ASSERT(spa_guid(spa) == pool_guid);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
index d072dc3aef79..994fb1c9df42 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
@@ -719,6 +719,9 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
spa->spa_debug = ((zfs_flags & ZFS_DEBUG_SPA) != 0);
+ spa->spa_min_ashift = INT_MAX;
+ spa->spa_max_ashift = 0;
+
/*
* As a pool is being created, treat all features as disabled by
* setting SPA_FEATURE_DISABLED for all entries in the feature
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
index d1737e13cfda..c656013c2507 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa_impl.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
@@ -147,6 +147,8 @@ struct spa {
objset_t *spa_meta_objset; /* copy of dp->dp_meta_objset */
txg_list_t spa_vdev_txg_list; /* per-txg dirty vdev list */
vdev_t *spa_root_vdev; /* top-level vdev container */
+ int spa_min_ashift; /* of vdevs in normal class */
+ int spa_max_ashift; /* of vdevs in normal class */
uint64_t spa_config_guid; /* config pool guid */
uint64_t spa_load_guid; /* spa_load initialized guid */
uint64_t spa_last_synced_guid; /* last synced guid */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
index e7515d5ae773..c14ac2165407 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
*/
#ifndef _SYS_VDEV_IMPL_H
@@ -225,7 +225,7 @@ struct vdev {
boolean_t vdev_isl2cache; /* was a l2cache device */
vdev_queue_t vdev_queue; /* I/O deadline schedule queue */
vdev_cache_t vdev_cache; /* physical block cache */
- spa_aux_vdev_t *vdev_aux; /* for l2cache vdevs */
+ spa_aux_vdev_t *vdev_aux; /* for l2cache and spares vdevs */
zio_t *vdev_probe_zio; /* root of current probe */
vdev_aux_t vdev_label_aux; /* on-disk aux state */
struct trim_map *vdev_trimmap; /* map on outstanding trims */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
index a3ec38e16f78..c434f0c4b4a0 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
@@ -21,8 +21,8 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
@@ -278,8 +278,9 @@ vdev_add_child(vdev_t *pvd, vdev_t *cvd)
size_t oldsize, newsize;
uint64_t id = cvd->vdev_id;
vdev_t **newchild;
+ spa_t *spa = cvd->vdev_spa;
- ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+ ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
ASSERT(cvd->vdev_parent == NULL);
cvd->vdev_parent = pvd;
@@ -1398,6 +1399,17 @@ vdev_open(vdev_t *vd)
}
/*
+ * Track the min and max ashift values for normal data devices.
+ */
+ if (vd->vdev_top == vd && vd->vdev_ashift != 0 &&
+ !vd->vdev_islog && vd->vdev_aux == NULL) {
+ if (vd->vdev_ashift > spa->spa_max_ashift)
+ spa->spa_max_ashift = vd->vdev_ashift;
+ if (vd->vdev_ashift < spa->spa_min_ashift)
+ spa->spa_min_ashift = vd->vdev_ashift;
+ }
+
+ /*
* If a leaf vdev has a DTL, and seems healthy, then kick off a
* resilver. But don't do this if we are doing a reopen for a scrub,
* since this would just restart the scrub we are already doing.
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
index 9e0b8a0998c3..c2dd020b4c0d 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c
@@ -697,6 +697,7 @@ zfsctl_unmount_snap(zfs_snapentry_t *sep, int fflags, cred_t *cr)
return (0);
#else
+ vfs_ref(vn_mountedvfs(svp));
return (dounmount(vn_mountedvfs(svp), fflags, curthread));
#endif
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index 8f31e3fe1211..e3b6581c862d 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -25,12 +25,11 @@
* All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright 2014 Xin Li <delphij@FreeBSD.org>. All rights reserved.
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
- * Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -3481,9 +3480,8 @@ zfs_unmount_snap(const char *snapname)
#ifdef illumos
(void) dounmount(vfsp, MS_FORCE, kcred);
#else
- mtx_lock(&Giant); /* dounmount() */
+ vfs_ref(vfsp);
(void) dounmount(vfsp, MS_FORCE, curthread);
- mtx_unlock(&Giant); /* dounmount() */
#endif
return (0);
}
@@ -5241,6 +5239,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
static int
zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
{
+ nvpair_t *pair;
nvlist_t *holds;
int cleanup_fd = -1;
int error;
@@ -5250,6 +5249,19 @@ zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
if (error != 0)
return (SET_ERROR(EINVAL));
+ /* make sure the user didn't pass us any invalid (empty) tags */
+ for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
+ pair = nvlist_next_nvpair(holds, pair)) {
+ char *htag;
+
+ error = nvpair_value_string(pair, &htag);
+ if (error != 0)
+ return (SET_ERROR(error));
+
+ if (strlen(htag) == 0)
+ return (SET_ERROR(EINVAL));
+ }
+
if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) {
error = zfs_onexit_fd_hold(cleanup_fd, &minor);
if (error != 0)
@@ -5363,11 +5375,19 @@ zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl)
return (error);
error = dsl_dataset_hold(dp, lastsnap, FTAG, &new);
+ if (error == 0 && !dsl_dataset_is_snapshot(new)) {
+ dsl_dataset_rele(new, FTAG);
+ error = SET_ERROR(EINVAL);
+ }
if (error != 0) {
dsl_pool_rele(dp, FTAG);
return (error);
}
error = dsl_dataset_hold(dp, firstsnap, FTAG, &old);
+ if (error == 0 && !dsl_dataset_is_snapshot(old)) {
+ dsl_dataset_rele(old, FTAG);
+ error = SET_ERROR(EINVAL);
+ }
if (error != 0) {
dsl_dataset_rele(new, FTAG);
dsl_pool_rele(dp, FTAG);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
index 5824828c7a07..1193e47a0108 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
@@ -2314,8 +2314,10 @@ bail:
* Since we couldn't setup the sa framework, try to force
* unmount this file system.
*/
- if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0)
+ if (vn_vfswlock(zfsvfs->z_vfs->vfs_vnodecovered) == 0) {
+ vfs_ref(zfsvfs->z_vfs);
(void) dounmount(zfsvfs->z_vfs, MS_FORCE, curthread);
+ }
}
return (err);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
index e3b314fef954..3d30082c6b7f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
@@ -1797,7 +1797,6 @@ log:
void
zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
{
- zfsvfs_t zfsvfs;
uint64_t moid, obj, sa_obj, version;
uint64_t sense = ZFS_CASE_SENSITIVE;
uint64_t norm = 0;
@@ -1805,6 +1804,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
int error;
int i;
znode_t *rootzp = NULL;
+ zfsvfs_t *zfsvfs;
vattr_t vattr;
znode_t *zp;
zfs_acl_ids_t acl_ids;
@@ -1880,7 +1880,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
vattr.va_uid = crgetuid(cr);
vattr.va_gid = crgetgid(cr);
- bzero(&zfsvfs, sizeof (zfsvfs_t));
+ zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP);
ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs));
@@ -1889,15 +1889,15 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
rootzp->z_atime_dirty = 0;
rootzp->z_is_sa = USE_SA(version, os);
- zfsvfs.z_os = os;
- zfsvfs.z_parent = &zfsvfs;
- zfsvfs.z_version = version;
- zfsvfs.z_use_fuids = USE_FUIDS(version, os);
- zfsvfs.z_use_sa = USE_SA(version, os);
- zfsvfs.z_norm = norm;
+ zfsvfs->z_os = os;
+ zfsvfs->z_parent = zfsvfs;
+ zfsvfs->z_version = version;
+ zfsvfs->z_use_fuids = USE_FUIDS(version, os);
+ zfsvfs->z_use_sa = USE_SA(version, os);
+ zfsvfs->z_norm = norm;
error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
- &zfsvfs.z_attr_table);
+ &zfsvfs->z_attr_table);
ASSERT(error == 0);
@@ -1906,16 +1906,16 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
* insensitive.
*/
if (sense == ZFS_CASE_INSENSITIVE || sense == ZFS_CASE_MIXED)
- zfsvfs.z_norm |= U8_TEXTPREP_TOUPPER;
+ zfsvfs->z_norm |= U8_TEXTPREP_TOUPPER;
- mutex_init(&zfsvfs.z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
- list_create(&zfsvfs.z_all_znodes, sizeof (znode_t),
+ mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
+ list_create(&zfsvfs->z_all_znodes, sizeof (znode_t),
offsetof(znode_t, z_link_node));
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
- mutex_init(&zfsvfs.z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
- rootzp->z_zfsvfs = &zfsvfs;
+ rootzp->z_zfsvfs = zfsvfs;
VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr,
cr, NULL, &acl_ids));
zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, &acl_ids);
@@ -1932,12 +1932,13 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx)
* Create shares directory
*/
- error = zfs_create_share_dir(&zfsvfs, tx);
+ error = zfs_create_share_dir(zfsvfs, tx);
ASSERT(error == 0);
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
- mutex_destroy(&zfsvfs.z_hold_mtx[i]);
+ mutex_destroy(&zfsvfs->z_hold_mtx[i]);
+ kmem_free(zfsvfs, sizeof (zfsvfs_t));
}
#endif /* _KERNEL */
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
index afda3e464f64..ae4d00c3866c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
*/
@@ -1264,19 +1264,23 @@ zio_write_bp_init(zio_t *zio)
return (ZIO_PIPELINE_CONTINUE);
} else {
/*
- * Round up compressed size to MINBLOCKSIZE and
- * zero the tail.
+ * Round up compressed size up to the ashift
+ * of the smallest-ashift device, and zero the tail.
+ * This ensures that the compressed size of the BP
+ * (and thus compressratio property) are correct,
+ * in that we charge for the padding used to fill out
+ * the last sector.
*/
- size_t rounded =
- P2ROUNDUP(psize, (size_t)SPA_MINBLOCKSIZE);
- if (rounded > psize) {
- bzero((char *)cbuf + psize, rounded - psize);
- psize = rounded;
- }
- if (psize == lsize) {
+ ASSERT3U(spa->spa_min_ashift, >=, SPA_MINBLOCKSHIFT);
+ size_t rounded = (size_t)P2ROUNDUP(psize,
+ 1ULL << spa->spa_min_ashift);
+ if (rounded >= lsize) {
compress = ZIO_COMPRESS_OFF;
zio_buf_free(cbuf, lsize);
+ psize = lsize;
} else {
+ bzero((char *)cbuf + psize, rounded - psize);
+ psize = rounded;
zio_push_transform(zio, cbuf,
psize, lsize, NULL);
}
diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
index a6c079ee6773..eb5856d1b51a 100644
--- a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
@@ -60,8 +60,6 @@
1: addq $TF_RIP,%rsp;
- .globl calltrap
- .type calltrap,@function
ENTRY(dtrace_invop_start)
/*
diff --git a/sys/cddl/dev/dtrace/arm/dtrace_asm.S b/sys/cddl/dev/dtrace/arm/dtrace_asm.S
index 06e91d2bd756..fd0ce6c86d0f 100644
--- a/sys/cddl/dev/dtrace/arm/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/arm/dtrace_asm.S
@@ -28,7 +28,6 @@
#define _ASM
#define _LOCORE
-#define LOCORE
#include <sys/cpuvar_defs.h>
#include <sys/dtrace.h>
diff --git a/sys/cddl/dev/dtrace/i386/dtrace_asm.S b/sys/cddl/dev/dtrace/i386/dtrace_asm.S
index d44f6c3fdf81..425e99c38980 100644
--- a/sys/cddl/dev/dtrace/i386/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/i386/dtrace_asm.S
@@ -34,8 +34,6 @@
#include "assym.s"
- .globl calltrap
- .type calltrap,@function
ENTRY(dtrace_invop_start)
pushl %eax /* push %eax -- may be return value */
diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c
index 6dd02aff96a5..51a9e9ff244a 100644
--- a/sys/compat/ia32/ia32_sysvec.c
+++ b/sys/compat/ia32/ia32_sysvec.c
@@ -136,6 +136,7 @@ struct sysentvec ia32_freebsd_sysvec = {
.sv_shared_page_base = FREEBSD32_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
INIT_SYSENTVEC(elf_ia32_sysvec, &ia32_freebsd_sysvec);
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index b2444c1a992d..25a832586c01 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -39,8 +39,6 @@
* @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
*/
-#include "opt_compat.h"
-
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -69,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
+#include <sys/sysent.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/tty.h>
@@ -80,7 +79,7 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <net/if_var.h>
-#include <net/vnet.h>
+#include <net/if_types.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -100,11 +99,7 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#endif /* __i386__ || __amd64__ */
-#ifdef COMPAT_FREEBSD32
-#include <compat/freebsd32/freebsd32_util.h>
-#endif
-
-#include <compat/linux/linux_ioctl.h>
+#include <compat/linux/linux.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_util.h>
@@ -748,6 +743,7 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
segsz_t lsize;
struct thread *td2;
struct sigacts *ps;
+ l_sigset_t siglist, sigignore, sigcatch;
int i;
sx_slock(&proctree_lock);
@@ -839,29 +835,25 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
/*
* Signal masks
- *
- * We support up to 128 signals, while Linux supports 32,
- * but we only define 32 (the same 32 as Linux, to boot), so
- * just show the lower 32 bits of each mask. XXX hack.
- *
- * NB: on certain platforms (Sparc at least) Linux actually
- * supports 64 signals, but this code is a long way from
- * running on anything but i386, so ignore that for now.
*/
PROC_LOCK(p);
- sbuf_printf(sb, "SigPnd:\t%08x\n", p->p_siglist.__bits[0]);
- /*
- * I can't seem to find out where the signal mask is in
- * relation to struct proc, so SigBlk is left unimplemented.
- */
- sbuf_printf(sb, "SigBlk:\t%08x\n", 0); /* XXX */
+ bsd_to_linux_sigset(&p->p_siglist, &siglist);
ps = p->p_sigacts;
mtx_lock(&ps->ps_mtx);
- sbuf_printf(sb, "SigIgn:\t%08x\n", ps->ps_sigignore.__bits[0]);
- sbuf_printf(sb, "SigCgt:\t%08x\n", ps->ps_sigcatch.__bits[0]);
+ bsd_to_linux_sigset(&ps->ps_sigignore, &sigignore);
+ bsd_to_linux_sigset(&ps->ps_sigcatch, &sigcatch);
mtx_unlock(&ps->ps_mtx);
PROC_UNLOCK(p);
+ sbuf_printf(sb, "SigPnd:\t%016jx\n", siglist.__mask);
+ /*
+ * XXX. SigBlk - target thread's signal mask, td_sigmask.
+ * To implement SigBlk pseudofs should support proc/tid dir entries.
+ */
+ sbuf_printf(sb, "SigBlk:\t%016x\n", 0);
+ sbuf_printf(sb, "SigIgn:\t%016jx\n", sigignore.__mask);
+ sbuf_printf(sb, "SigCgt:\t%016jx\n", sigcatch.__mask);
+
/*
* Linux also prints the capability masks, but we don't have
* capabilities yet, and when we do get them they're likely to
@@ -954,34 +946,22 @@ linprocfs_doproccmdline(PFS_FILL_ARGS)
static int
linprocfs_doprocenviron(PFS_FILL_ARGS)
{
- int ret;
-
- PROC_LOCK(p);
- if ((ret = p_candebug(td, p)) != 0) {
- PROC_UNLOCK(p);
- return (ret);
- }
/*
* Mimic linux behavior and pass only processes with usermode
* address space as valid. Return zero silently otherwize.
*/
- if (p->p_vmspace == &vmspace0) {
- PROC_UNLOCK(p);
- return (0);
- }
-
- if ((p->p_flag & P_SYSTEM) != 0) {
- PROC_UNLOCK(p);
+ if (p->p_vmspace == &vmspace0)
return (0);
- }
- PROC_UNLOCK(p);
-
- ret = proc_getenvv(td, p, sb);
- return (ret);
+ return (proc_getenvv(td, p, sb));
}
+static char l32_map_str[] = "%08lx-%08lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n";
+static char l64_map_str[] = "%016lx-%016lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n";
+static char vdso_str[] = " [vdso]";
+static char stack_str[] = " [stack]";
+
/*
* Filler function for proc/pid/maps
*/
@@ -997,6 +977,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
vm_prot_t e_prot;
unsigned int last_timestamp;
char *name = "", *freename = NULL;
+ const char *l_map_str;
ino_t ino;
int ref_count, shadow_count, flags;
int error;
@@ -1016,6 +997,11 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
vm = vmspace_acquire_ref(p);
if (vm == NULL)
return (ESRCH);
+
+ if (SV_CURPROC_FLAG(SV_LP64))
+ l_map_str = l64_map_str;
+ else
+ l_map_str = l32_map_str;
map = &vm->vm_map;
vm_map_lock_read(map);
for (entry = map->header.next; entry != &map->header;
@@ -1039,25 +1025,26 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
ino = 0;
if (lobj) {
off = IDX_TO_OFF(lobj->size);
- if (lobj->type == OBJT_VNODE) {
- vp = lobj->handle;
- if (vp)
- vref(vp);
- }
- else
- vp = NULL;
+ vp = vm_object_vnode(lobj);
+ if (vp != NULL)
+ vref(vp);
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
flags = obj->flags;
ref_count = obj->ref_count;
shadow_count = obj->shadow_count;
VM_OBJECT_RUNLOCK(obj);
- if (vp) {
+ if (vp != NULL) {
vn_fullpath(td, vp, &name, &freename);
vn_lock(vp, LK_SHARED | LK_RETRY);
VOP_GETATTR(vp, &vat, td->td_ucred);
ino = vat.va_fileid;
vput(vp);
+ } else if (SV_PROC_ABI(p) == SV_ABI_LINUX) {
+ if (e_start == p->p_sysent->sv_shared_page_base)
+ name = vdso_str;
+ if (e_end == p->p_sysent->sv_usrstack)
+ name = stack_str;
}
} else {
flags = 0;
@@ -1069,8 +1056,7 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
* format:
* start, end, access, offset, major, minor, inode, name.
*/
- error = sbuf_printf(sb,
- "%08lx-%08lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n",
+ error = sbuf_printf(sb, l_map_str,
(u_long)e_start, (u_long)e_end,
(e_prot & VM_PROT_READ)?"r":"-",
(e_prot & VM_PROT_WRITE)?"w":"-",
@@ -1107,6 +1093,35 @@ linprocfs_doprocmaps(PFS_FILL_ARGS)
}
/*
+ * Criteria for interface name translation
+ */
+#define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER)
+
+static int
+linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen)
+{
+ struct ifnet *ifscan;
+ int ethno;
+
+ IFNET_RLOCK_ASSERT();
+
+ /* Short-circuit non ethernet interfaces */
+ if (!IFP_IS_ETH(ifp))
+ return (strlcpy(buffer, ifp->if_xname, buflen));
+
+ /* Determine the (relative) unit number for ethernet interfaces */
+ ethno = 0;
+ TAILQ_FOREACH(ifscan, &V_ifnet, if_link) {
+ if (ifscan == ifp)
+ return (snprintf(buffer, buflen, "eth%d", ethno));
+ if (IFP_IS_ETH(ifscan))
+ ethno++;
+ }
+
+ return (0);
+}
+
+/*
* Filler function for proc/net/dev
*/
static int
@@ -1254,8 +1269,6 @@ linprocfs_doscsiscsi(PFS_FILL_ARGS)
return (0);
}
-extern struct cdevsw *cdevsw[];
-
/*
* Filler function for proc/devices
*/
@@ -1350,6 +1363,52 @@ linprocfs_douuid(PFS_FILL_ARGS)
return(0);
}
+/*
+ * Filler function for proc/pid/auxv
+ */
+static int
+linprocfs_doauxv(PFS_FILL_ARGS)
+{
+ struct sbuf *asb;
+ off_t buflen, resid;
+ int error;
+
+ /*
+ * Mimic linux behavior and pass only processes with usermode
+ * address space as valid. Return zero silently otherwise.
+ */
+ if (p->p_vmspace == &vmspace0)
+ return (0);
+
+ if (uio->uio_resid == 0)
+ return (0);
+ if (uio->uio_offset < 0 || uio->uio_resid < 0)
+ return (EINVAL);
+
+ asb = sbuf_new_auto();
+ if (asb == NULL)
+ return (ENOMEM);
+ error = proc_getauxv(td, p, asb);
+ if (error == 0)
+ error = sbuf_finish(asb);
+
+ resid = sbuf_len(asb) - uio->uio_offset;
+ if (resid > uio->uio_resid)
+ buflen = uio->uio_resid;
+ else
+ buflen = resid;
+ if (buflen > IOSIZE_MAX)
+ return (EINVAL);
+ if (buflen > MAXPHYS)
+ buflen = MAXPHYS;
+ if (resid <= 0)
+ return (0);
+
+ if (error == 0)
+ error = uiomove(sbuf_data(asb) + uio->uio_offset, buflen, uio);
+ sbuf_delete(asb);
+ return (error);
+}
/*
* Constructor
@@ -1408,7 +1467,7 @@ linprocfs_init(PFS_INIT_ARGS)
pfs_create_link(dir, "cwd", &linprocfs_doproccwd,
NULL, NULL, NULL, 0);
pfs_create_file(dir, "environ", &linprocfs_doprocenviron,
- NULL, NULL, NULL, PFS_RD);
+ NULL, &procfs_candebug, NULL, PFS_RD);
pfs_create_link(dir, "exe", &procfs_doprocfile,
NULL, &procfs_notsystem, NULL, 0);
pfs_create_file(dir, "maps", &linprocfs_doprocmaps,
@@ -1425,6 +1484,8 @@ linprocfs_init(PFS_INIT_ARGS)
NULL, NULL, NULL, PFS_RD);
pfs_create_link(dir, "fd", &linprocfs_dofdescfs,
NULL, NULL, NULL, 0);
+ pfs_create_file(dir, "auxv", &linprocfs_doauxv,
+ NULL, &procfs_candebug, NULL, PFS_RD|PFS_RAWRD);
/* /proc/scsi/... */
dir = pfs_create_dir(root, "scsi", NULL, NULL, NULL, 0);
@@ -1470,7 +1531,11 @@ linprocfs_uninit(PFS_INIT_ARGS)
}
PSEUDOFS(linprocfs, 1, 0);
+#if defined(__amd64__)
+MODULE_DEPEND(linprocfs, linux_common, 1, 1, 1);
+#else
MODULE_DEPEND(linprocfs, linux, 1, 1, 1);
+#endif
MODULE_DEPEND(linprocfs, procfs, 1, 1, 1);
MODULE_DEPEND(linprocfs, sysvmsg, 1, 1, 1);
MODULE_DEPEND(linprocfs, sysvsem, 1, 1, 1);
diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c
index 069e7ffc578b..bc85ac354eb6 100644
--- a/sys/compat/linsysfs/linsysfs.c
+++ b/sys/compat/linsysfs/linsysfs.c
@@ -62,12 +62,6 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
-#include "opt_compat.h"
-#ifdef COMPAT_LINUX32 /* XXX */
-#include <machine/../linux32/linux.h>
-#else
-#include <machine/../linux/linux.h>
-#endif
#include <compat/linux/linux_ioctl.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_util.h>
@@ -282,4 +276,8 @@ linsysfs_uninit(PFS_INIT_ARGS)
}
PSEUDOFS(linsysfs, 1, 0);
+#if defined(__amd64__)
+MODULE_DEPEND(linsysfs, linux_common, 1, 1, 1);
+#else
MODULE_DEPEND(linsysfs, linux, 1, 1, 1);
+#endif
diff --git a/sys/compat/linux/check_error.d b/sys/compat/linux/check_error.d
index 9e3c00a37dbe..389e768aa3f6 100644
--- a/sys/compat/linux/check_error.d
+++ b/sys/compat/linux/check_error.d
@@ -36,8 +36,8 @@
*/
linuxulator*:dummy::not_implemented,
-linuxulator*:emul:proc_exit:child_clear_tid_error,
-linuxulator*:emul:proc_exit:futex_failed,
+linuxulator*:emul:linux_thread_detach:child_clear_tid_error,
+linuxulator*:emul:linux_thread_detach:futex_failed,
linuxulator*:emul:linux_schedtail:copyout_error,
linuxulator*:futex:futex_get:error,
linuxulator*:futex:futex_sleep:requeue_error,
diff --git a/sys/compat/linux/check_internal_locks.d b/sys/compat/linux/check_internal_locks.d
index 2bdef684fadb..b9d7c61f82ca 100644
--- a/sys/compat/linux/check_internal_locks.d
+++ b/sys/compat/linux/check_internal_locks.d
@@ -41,14 +41,9 @@
BEGIN
{
- check["emul_lock"] = 0;
- check["emul_shared_rlock"] = 0;
- check["emul_shared_wlock"] = 0;
check["futex_mtx"] = 0;
}
-linuxulator*:locks:emul_lock:locked,
-linuxulator*:locks:emul_shared_wlock:locked,
linuxulator*:locks:futex_mtx:locked
/check[probefunc] > 0/
{
@@ -57,9 +52,6 @@ linuxulator*:locks:futex_mtx:locked
stack();
}
-linuxulator*:locks:emul_lock:locked,
-linuxulator*:locks:emul_shared_rlock:locked,
-linuxulator*:locks:emul_shared_wlock:locked,
linuxulator*:locks:futex_mtx:locked
{
++check[probefunc];
@@ -69,9 +61,6 @@ linuxulator*:locks:futex_mtx:locked
spec[probefunc] = speculation();
}
-linuxulator*:locks:emul_lock:unlock,
-linuxulator*:locks:emul_shared_rlock:unlock,
-linuxulator*:locks:emul_shared_wlock:unlock,
linuxulator*:locks:futex_mtx:unlock
/check[probefunc] == 0/
{
@@ -82,9 +71,6 @@ linuxulator*:locks:futex_mtx:unlock
stack();
}
-linuxulator*:locks:emul_lock:unlock,
-linuxulator*:locks:emul_shared_rlock:unlock,
-linuxulator*:locks:emul_shared_wlock:unlock,
linuxulator*:locks:futex_mtx:unlock
{
discard(spec[probefunc]);
@@ -95,27 +81,6 @@ linuxulator*:locks:futex_mtx:unlock
/* Timeout handling */
tick-10s
-/spec["emul_lock"] != 0 && timestamp - ts["emul_lock"] >= 9999999000/
-{
- commit(spec["emul_lock"]);
- spec["emul_lock"] = 0;
-}
-
-tick-10s
-/spec["emul_shared_wlock"] != 0 && timestamp - ts["emul_shared_wlock"] >= 9999999000/
-{
- commit(spec["emul_shared_wlock"]);
- spec["emul_shared_wlock"] = 0;
-}
-
-tick-10s
-/spec["emul_shared_rlock"] != 0 && timestamp - ts["emul_shared_rlock"] >= 9999999000/
-{
- commit(spec["emul_shared_rlock"]);
- spec["emul_shared_rlock"] = 0;
-}
-
-tick-10s
/spec["futex_mtx"] != 0 && timestamp - ts["futex_mtx"] >= 9999999000/
{
commit(spec["futex_mtx"]);
diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c
new file mode 100644
index 000000000000..d1d787742c63
--- /dev/null
+++ b/sys/compat/linux/linux.c
@@ -0,0 +1,205 @@
+/*-
+ * Copyright (c) 2015 Dmitry Chagin
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+
+#include <compat/linux/linux.h>
+
+
+static int bsd_to_linux_sigtbl[LINUX_SIGTBLSZ] = {
+ LINUX_SIGHUP, /* SIGHUP */
+ LINUX_SIGINT, /* SIGINT */
+ LINUX_SIGQUIT, /* SIGQUIT */
+ LINUX_SIGILL, /* SIGILL */
+ LINUX_SIGTRAP, /* SIGTRAP */
+ LINUX_SIGABRT, /* SIGABRT */
+ 0, /* SIGEMT */
+ LINUX_SIGFPE, /* SIGFPE */
+ LINUX_SIGKILL, /* SIGKILL */
+ LINUX_SIGBUS, /* SIGBUS */
+ LINUX_SIGSEGV, /* SIGSEGV */
+ LINUX_SIGSYS, /* SIGSYS */
+ LINUX_SIGPIPE, /* SIGPIPE */
+ LINUX_SIGALRM, /* SIGALRM */
+ LINUX_SIGTERM, /* SIGTERM */
+ LINUX_SIGURG, /* SIGURG */
+ LINUX_SIGSTOP, /* SIGSTOP */
+ LINUX_SIGTSTP, /* SIGTSTP */
+ LINUX_SIGCONT, /* SIGCONT */
+ LINUX_SIGCHLD, /* SIGCHLD */
+ LINUX_SIGTTIN, /* SIGTTIN */
+ LINUX_SIGTTOU, /* SIGTTOU */
+ LINUX_SIGIO, /* SIGIO */
+ LINUX_SIGXCPU, /* SIGXCPU */
+ LINUX_SIGXFSZ, /* SIGXFSZ */
+ LINUX_SIGVTALRM,/* SIGVTALRM */
+ LINUX_SIGPROF, /* SIGPROF */
+ LINUX_SIGWINCH, /* SIGWINCH */
+ 0, /* SIGINFO */
+ LINUX_SIGUSR1, /* SIGUSR1 */
+ LINUX_SIGUSR2 /* SIGUSR2 */
+};
+
+static int linux_to_bsd_sigtbl[LINUX_SIGTBLSZ] = {
+ SIGHUP, /* LINUX_SIGHUP */
+ SIGINT, /* LINUX_SIGINT */
+ SIGQUIT, /* LINUX_SIGQUIT */
+ SIGILL, /* LINUX_SIGILL */
+ SIGTRAP, /* LINUX_SIGTRAP */
+ SIGABRT, /* LINUX_SIGABRT */
+ SIGBUS, /* LINUX_SIGBUS */
+ SIGFPE, /* LINUX_SIGFPE */
+ SIGKILL, /* LINUX_SIGKILL */
+ SIGUSR1, /* LINUX_SIGUSR1 */
+ SIGSEGV, /* LINUX_SIGSEGV */
+ SIGUSR2, /* LINUX_SIGUSR2 */
+ SIGPIPE, /* LINUX_SIGPIPE */
+ SIGALRM, /* LINUX_SIGALRM */
+ SIGTERM, /* LINUX_SIGTERM */
+ SIGBUS, /* LINUX_SIGSTKFLT */
+ SIGCHLD, /* LINUX_SIGCHLD */
+ SIGCONT, /* LINUX_SIGCONT */
+ SIGSTOP, /* LINUX_SIGSTOP */
+ SIGTSTP, /* LINUX_SIGTSTP */
+ SIGTTIN, /* LINUX_SIGTTIN */
+ SIGTTOU, /* LINUX_SIGTTOU */
+ SIGURG, /* LINUX_SIGURG */
+ SIGXCPU, /* LINUX_SIGXCPU */
+ SIGXFSZ, /* LINUX_SIGXFSZ */
+ SIGVTALRM, /* LINUX_SIGVTALARM */
+ SIGPROF, /* LINUX_SIGPROF */
+ SIGWINCH, /* LINUX_SIGWINCH */
+ SIGIO, /* LINUX_SIGIO */
+ /*
+ * FreeBSD does not have SIGPWR signal, map Linux SIGPWR signal
+ * to the first unused FreeBSD signal number. Since Linux supports
+ * signals from 1 to 64 we are ok here as our SIGRTMIN = 65.
+ */
+ SIGRTMIN, /* LINUX_SIGPWR */
+ SIGSYS /* LINUX_SIGSYS */
+};
+
+/*
+ * Map Linux RT signals to the FreeBSD RT signals.
+ */
+static inline int
+linux_to_bsd_rt_signal(int sig)
+{
+
+ return (SIGRTMIN + 1 + sig - LINUX_SIGRTMIN);
+}
+
+static inline int
+bsd_to_linux_rt_signal(int sig)
+{
+
+ return (sig - SIGRTMIN - 1 + LINUX_SIGRTMIN);
+}
+
+int
+linux_to_bsd_signal(int sig)
+{
+
+ KASSERT(sig > 0 && sig <= LINUX_SIGRTMAX, ("Invalid Linux signal\n"));
+
+ if (sig < LINUX_SIGRTMIN)
+ return (linux_to_bsd_sigtbl[_SIG_IDX(sig)]);
+
+ return (linux_to_bsd_rt_signal(sig));
+}
+
+int
+bsd_to_linux_signal(int sig)
+{
+
+ if (sig <= LINUX_SIGTBLSZ)
+ return (bsd_to_linux_sigtbl[_SIG_IDX(sig)]);
+ if (sig == SIGRTMIN)
+ return (LINUX_SIGPWR);
+
+ return (bsd_to_linux_rt_signal(sig));
+}
+
+int
+linux_to_bsd_sigaltstack(int lsa)
+{
+ int bsa = 0;
+
+ if (lsa & LINUX_SS_DISABLE)
+ bsa |= SS_DISABLE;
+ /*
+ * Linux ignores SS_ONSTACK flag for ss
+ * parameter while FreeBSD prohibits it.
+ */
+ return (bsa);
+}
+
+int
+bsd_to_linux_sigaltstack(int bsa)
+{
+ int lsa = 0;
+
+ if (bsa & SS_DISABLE)
+ lsa |= LINUX_SS_DISABLE;
+ if (bsa & SS_ONSTACK)
+ lsa |= LINUX_SS_ONSTACK;
+ return (lsa);
+}
+
+void
+linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
+{
+ int b, l;
+
+ SIGEMPTYSET(*bss);
+ for (l = 1; l <= LINUX_SIGRTMAX; l++) {
+ if (LINUX_SIGISMEMBER(*lss, l)) {
+ b = linux_to_bsd_signal(l);
+ if (b)
+ SIGADDSET(*bss, b);
+ }
+ }
+}
+
+void
+bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
+{
+ int b, l;
+
+ LINUX_SIGEMPTYSET(*lss);
+ for (b = 1; b <= SIGRTMAX; b++) {
+ if (SIGISMEMBER(*bss, b)) {
+ l = bsd_to_linux_signal(b);
+ if (l)
+ LINUX_SIGADDSET(*lss, l);
+ }
+ }
+}
diff --git a/sys/compat/linux/linux.h b/sys/compat/linux/linux.h
new file mode 100644
index 000000000000..974440f94c26
--- /dev/null
+++ b/sys/compat/linux/linux.h
@@ -0,0 +1,95 @@
+/*-
+ * Copyright (c) 2015 Dmitry Chagin
+ * 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$
+ */
+
+#ifndef _LINUX_MI_H_
+#define _LINUX_MI_H_
+
+/* sigaltstack */
+#define LINUX_SS_ONSTACK 1
+#define LINUX_SS_DISABLE 2
+
+int linux_to_bsd_sigaltstack(int lsa);
+int bsd_to_linux_sigaltstack(int bsa);
+
+/* sigset */
+typedef struct {
+ uint64_t __mask;
+} l_sigset_t;
+
+/* primitives to manipulate sigset_t */
+#define LINUX_SIGEMPTYSET(set) (set).__mask = 0
+#define LINUX_SIGISMEMBER(set, sig) (1UL & ((set).__mask >> _SIG_IDX(sig)))
+#define LINUX_SIGADDSET(set, sig) (set).__mask |= 1UL << _SIG_IDX(sig)
+
+void linux_to_bsd_sigset(l_sigset_t *, sigset_t *);
+void bsd_to_linux_sigset(sigset_t *, l_sigset_t *);
+
+/* signaling */
+#define LINUX_SIGHUP 1
+#define LINUX_SIGINT 2
+#define LINUX_SIGQUIT 3
+#define LINUX_SIGILL 4
+#define LINUX_SIGTRAP 5
+#define LINUX_SIGABRT 6
+#define LINUX_SIGIOT LINUX_SIGABRT
+#define LINUX_SIGBUS 7
+#define LINUX_SIGFPE 8
+#define LINUX_SIGKILL 9
+#define LINUX_SIGUSR1 10
+#define LINUX_SIGSEGV 11
+#define LINUX_SIGUSR2 12
+#define LINUX_SIGPIPE 13
+#define LINUX_SIGALRM 14
+#define LINUX_SIGTERM 15
+#define LINUX_SIGSTKFLT 16
+#define LINUX_SIGCHLD 17
+#define LINUX_SIGCONT 18
+#define LINUX_SIGSTOP 19
+#define LINUX_SIGTSTP 20
+#define LINUX_SIGTTIN 21
+#define LINUX_SIGTTOU 22
+#define LINUX_SIGURG 23
+#define LINUX_SIGXCPU 24
+#define LINUX_SIGXFSZ 25
+#define LINUX_SIGVTALRM 26
+#define LINUX_SIGPROF 27
+#define LINUX_SIGWINCH 28
+#define LINUX_SIGIO 29
+#define LINUX_SIGPOLL LINUX_SIGIO
+#define LINUX_SIGPWR 30
+#define LINUX_SIGSYS 31
+#define LINUX_SIGTBLSZ 31
+#define LINUX_SIGRTMIN 32
+#define LINUX_SIGRTMAX 64
+
+#define LINUX_SIG_VALID(sig) ((sig) <= LINUX_SIGRTMAX && (sig) > 0)
+
+int linux_to_bsd_signal(int sig);
+int bsd_to_linux_signal(int sig);
+
+#endif /* _LINUX_MI_H_ */
diff --git a/sys/compat/linux/linux_common.c b/sys/compat/linux/linux_common.c
new file mode 100644
index 000000000000..b9e35311bdfe
--- /dev/null
+++ b/sys/compat/linux/linux_common.c
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2014 Vassilis Laganakos
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/eventhandler.h>
+#include <sys/sysctl.h>
+
+#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_mib.h>
+#include <compat/linux/linux_util.h>
+
+FEATURE(linuxulator_v4l, "V4L ioctl wrapper support in the linuxulator");
+FEATURE(linuxulator_v4l2, "V4L2 ioctl wrapper support in the linuxulator");
+
+MODULE_VERSION(linux_common, 1);
+
+SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
+
+static eventhandler_tag linux_exec_tag;
+static eventhandler_tag linux_thread_dtor_tag;
+static eventhandler_tag linux_exit_tag;
+
+
+static int
+linux_common_modevent(module_t mod, int type, void *data)
+{
+ struct linux_device_handler **ldhp;
+
+ switch(type) {
+ case MOD_LOAD:
+ linux_osd_jail_register();
+ linux_exit_tag = EVENTHANDLER_REGISTER(process_exit,
+ linux_proc_exit, NULL, 1000);
+ linux_exec_tag = EVENTHANDLER_REGISTER(process_exec,
+ linux_proc_exec, NULL, 1000);
+ linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor,
+ linux_thread_dtor, NULL, EVENTHANDLER_PRI_ANY);
+ SET_FOREACH(ldhp, linux_device_handler_set)
+ linux_device_register_handler(*ldhp);
+ break;
+ case MOD_UNLOAD:
+ linux_osd_jail_deregister();
+ SET_FOREACH(ldhp, linux_device_handler_set)
+ linux_device_unregister_handler(*ldhp);
+ EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
+ EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
+ EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag);
+ break;
+ default:
+ return (EOPNOTSUPP);
+ }
+ return (0);
+}
+
+static moduledata_t linux_common_mod = {
+ "linuxcommon",
+ linux_common_modevent,
+ 0
+};
+
+DECLARE_MODULE(linuxcommon, linux_common_mod, SI_SUB_EXEC, SI_ORDER_ANY);
diff --git a/sys/compat/linux/linux_emul.c b/sys/compat/linux/linux_emul.c
index ec19cd9e74b0..c2bf3aeb80a3 100644
--- a/sys/compat/linux/linux_emul.c
+++ b/sys/compat/linux/linux_emul.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2006 Roman Divacky
+ * Copyright (c) 2013 Dmitry Chagin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,363 +30,235 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "opt_compat.h"
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/imgact.h>
#include <sys/kernel.h>
+#include <sys/ktr.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
-#include <sys/sdt.h>
#include <sys/sx.h>
#include <sys/proc.h>
#include <sys/syscallsubr.h>
#include <sys/sysent.h>
-#include <sys/sysproto.h>
-#include <sys/unistd.h>
-
-#ifdef COMPAT_LINUX32
-#include <machine/../linux32/linux.h>
-#include <machine/../linux32/linux32_proto.h>
-#else
-#include <machine/../linux/linux.h>
-#include <machine/../linux/linux_proto.h>
-#endif
-
-#include <compat/linux/linux_dtrace.h>
+
#include <compat/linux/linux_emul.h>
-#include <compat/linux/linux_futex.h>
#include <compat/linux/linux_misc.h>
+#include <compat/linux/linux_util.h>
-/**
- * Special DTrace provider for the linuxulator.
- *
- * In this file we define the provider for the entire linuxulator. All
- * modules (= files of the linuxulator) use it.
- *
- * We define a different name depending on the emulated bitsize, see
- * ../../<ARCH>/linux{,32}/linux.h, e.g.:
- * native bitsize = linuxulator
- * amd64, 32bit emulation = linuxulator32
- */
-LIN_SDT_PROVIDER_DEFINE(LINUX_DTRACE);
-/**
- * Special DTrace module "locks", it covers some linuxulator internal
- * locks.
- */
-LIN_SDT_PROBE_DEFINE1(locks, emul_lock, locked, "struct mtx *");
-LIN_SDT_PROBE_DEFINE1(locks, emul_lock, unlock, "struct mtx *");
-LIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, locked, "struct sx *");
-LIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, unlock, "struct sx *");
-LIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, locked, "struct sx *");
-LIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, unlock, "struct sx *");
-
-/**
- * DTrace probes in this module.
+/*
+ * This returns reference to the thread emuldata entry (if found)
+ *
+ * Hold PROC_LOCK when referencing emuldata from other threads.
*/
-LIN_SDT_PROBE_DEFINE2(emul, em_find, entry, "struct proc *", "int");
-LIN_SDT_PROBE_DEFINE0(emul, em_find, return);
-LIN_SDT_PROBE_DEFINE3(emul, proc_init, entry, "struct thread *", "pid_t",
- "int");
-LIN_SDT_PROBE_DEFINE0(emul, proc_init, create_thread);
-LIN_SDT_PROBE_DEFINE0(emul, proc_init, fork);
-LIN_SDT_PROBE_DEFINE0(emul, proc_init, exec);
-LIN_SDT_PROBE_DEFINE0(emul, proc_init, return);
-LIN_SDT_PROBE_DEFINE1(emul, proc_exit, entry, "struct proc *");
-LIN_SDT_PROBE_DEFINE0(emul, proc_exit, futex_failed);
-LIN_SDT_PROBE_DEFINE3(emul, proc_exit, reparent, "pid_t", "pid_t",
- "struct proc *");
-LIN_SDT_PROBE_DEFINE1(emul, proc_exit, child_clear_tid_error, "int");
-LIN_SDT_PROBE_DEFINE0(emul, proc_exit, return);
-LIN_SDT_PROBE_DEFINE2(emul, proc_exec, entry, "struct proc *",
- "struct image_params *");
-LIN_SDT_PROBE_DEFINE0(emul, proc_exec, return);
-LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, entry);
-LIN_SDT_PROBE_DEFINE1(emul, linux_schedtail, copyout_error, "int");
-LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, return);
-LIN_SDT_PROBE_DEFINE1(emul, linux_set_tid_address, entry, "int *");
-LIN_SDT_PROBE_DEFINE0(emul, linux_set_tid_address, return);
-LIN_SDT_PROBE_DEFINE2(emul, linux_kill_threads, entry, "struct thread *",
- "int");
-LIN_SDT_PROBE_DEFINE1(emul, linux_kill_threads, kill, "pid_t");
-LIN_SDT_PROBE_DEFINE0(emul, linux_kill_threads, return);
-
-struct sx emul_shared_lock;
-struct mtx emul_lock;
-
-/* this returns locked reference to the emuldata entry (if found) */
struct linux_emuldata *
-em_find(struct proc *p, int locked)
+em_find(struct thread *td)
{
struct linux_emuldata *em;
- LIN_SDT_PROBE2(emul, em_find, entry, p, locked);
+ em = td->td_emuldata;
- if (locked == EMUL_DOLOCK)
- EMUL_LOCK(&emul_lock);
+ return (em);
+}
- em = p->p_emuldata;
+/*
+ * This returns reference to the proc pemuldata entry (if found)
+ *
+ * Hold PROC_LOCK when referencing proc pemuldata from other threads.
+ * Hold LINUX_PEM_LOCK wher referencing pemuldata members.
+ */
+struct linux_pemuldata *
+pem_find(struct proc *p)
+{
+ struct linux_pemuldata *pem;
- if (em == NULL && locked == EMUL_DOLOCK)
- EMUL_UNLOCK(&emul_lock);
+ pem = p->p_emuldata;
- LIN_SDT_PROBE1(emul, em_find, return, em);
- return (em);
+ return (pem);
}
-int
-linux_proc_init(struct thread *td, pid_t child, int flags)
+void
+linux_proc_init(struct thread *td, struct thread *newtd, int flags)
{
- struct linux_emuldata *em, *p_em;
+ struct linux_emuldata *em;
+ struct linux_pemuldata *pem;
+ struct epoll_emuldata *emd;
struct proc *p;
- LIN_SDT_PROBE3(emul, proc_init, entry, td, child, flags);
+ if (newtd != NULL) {
+ p = newtd->td_proc;
- if (child != 0) {
- /* fork or create a thread */
- em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO);
- em->pid = child;
- em->pdeath_signal = 0;
- em->flags = 0;
- em->robust_futexes = NULL;
+ /* non-exec call */
+ em = malloc(sizeof(*em), M_TEMP, M_WAITOK | M_ZERO);
if (flags & LINUX_CLONE_THREAD) {
- /* handled later in the code */
- LIN_SDT_PROBE0(emul, proc_init, create_thread);
- } else {
- struct linux_emuldata_shared *s;
+ LINUX_CTR1(proc_init, "thread newtd(%d)",
+ newtd->td_tid);
- LIN_SDT_PROBE0(emul, proc_init, fork);
+ em->em_tid = newtd->td_tid;
+ } else {
+ LINUX_CTR1(proc_init, "fork newtd(%d)", p->p_pid);
- s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO);
- s->refs = 1;
- s->group_pid = child;
+ em->em_tid = p->p_pid;
- LIST_INIT(&s->threads);
- em->shared = s;
+ pem = malloc(sizeof(*pem), M_LINUX, M_WAITOK | M_ZERO);
+ sx_init(&pem->pem_sx, "lpemlk");
+ p->p_emuldata = pem;
}
+ newtd->td_emuldata = em;
} else {
+ p = td->td_proc;
+
/* exec */
- LIN_SDT_PROBE0(emul, proc_init, exec);
+ LINUX_CTR1(proc_init, "exec newtd(%d)", p->p_pid);
/* lookup the old one */
- em = em_find(td->td_proc, EMUL_DOLOCK);
+ em = em_find(td);
KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n"));
- }
-
- em->child_clear_tid = NULL;
- em->child_set_tid = NULL;
- /*
- * allocate the shared struct only in clone()/fork cases in the case
- * of clone() td = calling proc and child = pid of the newly created
- * proc
- */
- if (child != 0) {
- if (flags & LINUX_CLONE_THREAD) {
- /* lookup the parent */
- /*
- * we dont have to lock the p_em because
- * its waiting for us in linux_clone so
- * there is no chance of it changing the
- * p_em->shared address
- */
- p_em = em_find(td->td_proc, EMUL_DONTLOCK);
- KASSERT(p_em != NULL, ("proc_init: parent emuldata not found for CLONE_THREAD\n"));
- em->shared = p_em->shared;
- EMUL_SHARED_WLOCK(&emul_shared_lock);
- em->shared->refs++;
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
- } else {
- /*
- * handled earlier to avoid malloc(M_WAITOK) with
- * rwlock held
- */
- }
+ em->em_tid = p->p_pid;
+ em->flags = 0;
+ em->pdeath_signal = 0;
+ em->robust_futexes = NULL;
+ em->child_clear_tid = NULL;
+ em->child_set_tid = NULL;
- EMUL_SHARED_WLOCK(&emul_shared_lock);
- LIST_INSERT_HEAD(&em->shared->threads, em, threads);
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
+ /* epoll should be destroyed in a case of exec. */
+ pem = pem_find(p);
+ KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n"));
- p = pfind(child);
- KASSERT(p != NULL, ("process not found in proc_init\n"));
- p->p_emuldata = em;
- PROC_UNLOCK(p);
- } else
- EMUL_UNLOCK(&emul_lock);
+ if (pem->epoll != NULL) {
+ emd = pem->epoll;
+ pem->epoll = NULL;
+ free(emd, M_EPOLL);
+ }
+ }
- LIN_SDT_PROBE0(emul, proc_init, return);
- return (0);
}
-void
+void
linux_proc_exit(void *arg __unused, struct proc *p)
{
- struct linux_emuldata *em;
- int error, shared_flags, shared_xstat;
- struct thread *td = FIRST_THREAD_IN_PROC(p);
- int *child_clear_tid;
- struct proc *q, *nq;
+ struct linux_pemuldata *pem;
+ struct epoll_emuldata *emd;
+ struct thread *td = curthread;
- if (__predict_true(p->p_sysent != &elf_linux_sysvec))
+ if (__predict_false(SV_CURPROC_ABI() != SV_ABI_LINUX))
return;
- LIN_SDT_PROBE1(emul, proc_exit, entry, p);
-
- release_futexes(p);
+ LINUX_CTR3(proc_exit, "thread(%d) proc(%d) p %p",
+ td->td_tid, p->p_pid, p);
- /* find the emuldata */
- em = em_find(p, EMUL_DOLOCK);
+ pem = pem_find(p);
+ if (pem == NULL)
+ return;
+ (p->p_sysent->sv_thread_detach)(td);
- KASSERT(em != NULL, ("proc_exit: emuldata not found.\n"));
+ p->p_emuldata = NULL;
- /* reparent all procs that are not a thread leader to initproc */
- if (em->shared->group_pid != p->p_pid) {
- LIN_SDT_PROBE3(emul, proc_exit, reparent,
- em->shared->group_pid, p->p_pid, p);
-
- child_clear_tid = em->child_clear_tid;
- EMUL_UNLOCK(&emul_lock);
- sx_xlock(&proctree_lock);
- wakeup(initproc);
- PROC_LOCK(p);
- proc_reparent(p, initproc);
- p->p_sigparent = SIGCHLD;
- PROC_UNLOCK(p);
- sx_xunlock(&proctree_lock);
- } else {
- child_clear_tid = em->child_clear_tid;
- EMUL_UNLOCK(&emul_lock);
+ if (pem->epoll != NULL) {
+ emd = pem->epoll;
+ pem->epoll = NULL;
+ free(emd, M_EPOLL);
}
- EMUL_SHARED_WLOCK(&emul_shared_lock);
- shared_flags = em->shared->flags;
- shared_xstat = em->shared->xstat;
- LIST_REMOVE(em, threads);
+ sx_destroy(&pem->pem_sx);
+ free(pem, M_LINUX);
+}
- em->shared->refs--;
- if (em->shared->refs == 0) {
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
- free(em->shared, M_LINUX);
- } else
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
+int
+linux_common_execve(struct thread *td, struct image_args *eargs)
+{
+ struct linux_pemuldata *pem;
+ struct epoll_emuldata *emd;
+ struct vmspace *oldvmspace;
+ struct linux_emuldata *em;
+ struct proc *p;
+ int error;
- if ((shared_flags & EMUL_SHARED_HASXSTAT) != 0)
- p->p_xstat = shared_xstat;
+ p = td->td_proc;
- if (child_clear_tid != NULL) {
- struct linux_sys_futex_args cup;
- int null = 0;
+ error = pre_execve(td, &oldvmspace);
+ if (error != 0)
+ return (error);
- error = copyout(&null, child_clear_tid, sizeof(null));
- if (error) {
- LIN_SDT_PROBE1(emul, proc_exit,
- child_clear_tid_error, error);
+ error = kern_execve(td, eargs, NULL);
+ post_execve(td, error, oldvmspace);
+ if (error != 0)
+ return (error);
- free(em, M_LINUX);
+ /*
+ * In a case of transition from Linux binary execing to
+ * FreeBSD binary we destroy linux emuldata thread & proc entries.
+ */
+ if (SV_CURPROC_ABI() != SV_ABI_LINUX) {
+ PROC_LOCK(p);
+ em = em_find(td);
+ KASSERT(em != NULL, ("proc_exec: thread emuldata not found.\n"));
+ td->td_emuldata = NULL;
- LIN_SDT_PROBE0(emul, proc_exit, return);
- return;
- }
+ pem = pem_find(p);
+ KASSERT(pem != NULL, ("proc_exec: proc pemuldata not found.\n"));
+ p->p_emuldata = NULL;
+ PROC_UNLOCK(p);
- /* futexes stuff */
- cup.uaddr = child_clear_tid;
- cup.op = LINUX_FUTEX_WAKE;
- cup.val = 0x7fffffff; /* Awake everyone */
- cup.timeout = NULL;
- cup.uaddr2 = NULL;
- cup.val3 = 0;
- error = linux_sys_futex(FIRST_THREAD_IN_PROC(p), &cup);
- /*
- * this cannot happen at the moment and if this happens it
- * probably means there is a user space bug
- */
- if (error) {
- LIN_SDT_PROBE0(emul, proc_exit, futex_failed);
- printf(LMSG("futex stuff in proc_exit failed.\n"));
+ if (pem->epoll != NULL) {
+ emd = pem->epoll;
+ pem->epoll = NULL;
+ free(emd, M_EPOLL);
}
- }
- /* clean the stuff up */
- free(em, M_LINUX);
-
- /* this is a little weird but rewritten from exit1() */
- sx_xlock(&proctree_lock);
- q = LIST_FIRST(&p->p_children);
- for (; q != NULL; q = nq) {
- nq = LIST_NEXT(q, p_sibling);
- if (q->p_flag & P_WEXIT)
- continue;
- if (__predict_false(q->p_sysent != &elf_linux_sysvec))
- continue;
- em = em_find(q, EMUL_DOLOCK);
- KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid));
- PROC_LOCK(q);
- if ((q->p_flag & P_WEXIT) == 0 && em->pdeath_signal != 0) {
- kern_psignal(q, em->pdeath_signal);
- }
- PROC_UNLOCK(q);
- EMUL_UNLOCK(&emul_lock);
+ free(em, M_TEMP);
+ free(pem, M_LINUX);
}
- sx_xunlock(&proctree_lock);
-
- LIN_SDT_PROBE0(emul, proc_exit, return);
+ return (0);
}
-/*
- * This is used in a case of transition from FreeBSD binary execing to linux binary
- * in this case we create linux emuldata proc entry with the pid of the currently running
- * process.
- */
void
linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
{
- if (__predict_false(imgp->sysent == &elf_linux_sysvec)) {
- LIN_SDT_PROBE2(emul, proc_exec, entry, p, imgp);
- }
- if (__predict_false(imgp->sysent == &elf_linux_sysvec
- && p->p_sysent != &elf_linux_sysvec))
- linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0);
- if (__predict_false((p->p_sysent->sv_flags & SV_ABI_MASK) ==
- SV_ABI_LINUX))
- /* Kill threads regardless of imgp->sysent value */
- linux_kill_threads(FIRST_THREAD_IN_PROC(p), SIGKILL);
- if (__predict_false(imgp->sysent != &elf_linux_sysvec
- && p->p_sysent == &elf_linux_sysvec)) {
- struct linux_emuldata *em;
-
- /*
- * XXX:There's a race because here we assign p->p_emuldata NULL
- * but the process is still counted as linux one for a short
- * time so some other process might reference it and try to
- * access its p->p_emuldata and panicing on a NULL reference.
- */
- em = em_find(p, EMUL_DONTLOCK);
-
- KASSERT(em != NULL, ("proc_exec: emuldata not found.\n"));
-
- EMUL_SHARED_WLOCK(&emul_shared_lock);
- LIST_REMOVE(em, threads);
+ struct thread *td = curthread;
+ struct thread *othertd;
- PROC_LOCK(p);
- p->p_emuldata = NULL;
- PROC_UNLOCK(p);
+ /*
+ * In a case of execing from linux binary properly detach
+ * other threads from the user space.
+ */
+ if (__predict_false(SV_PROC_ABI(p) == SV_ABI_LINUX)) {
+ FOREACH_THREAD_IN_PROC(p, othertd) {
+ if (td != othertd)
+ (p->p_sysent->sv_thread_detach)(othertd);
+ }
+ }
- em->shared->refs--;
- if (em->shared->refs == 0) {
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
- free(em->shared, M_LINUX);
- } else
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
+ /*
+ * In a case of execing to linux binary we create linux
+ * emuldata thread entry.
+ */
+ if (__predict_false((imgp->sysent->sv_flags & SV_ABI_MASK) ==
+ SV_ABI_LINUX)) {
- free(em, M_LINUX);
+ if (SV_PROC_ABI(p) == SV_ABI_LINUX)
+ linux_proc_init(td, NULL, 0);
+ else
+ linux_proc_init(td, td, 0);
}
+}
- if (__predict_false(imgp->sysent == &elf_linux_sysvec)) {
- LIN_SDT_PROBE0(emul, proc_exec, return);
- }
+void
+linux_thread_dtor(void *arg __unused, struct thread *td)
+{
+ struct linux_emuldata *em;
+
+ em = em_find(td);
+ if (em == NULL)
+ return;
+ td->td_emuldata = NULL;
+
+ LINUX_CTR1(thread_dtor, "thread(%d)", em->em_tid);
+
+ free(em, M_TEMP);
}
void
@@ -398,76 +271,15 @@ linux_schedtail(struct thread *td)
p = td->td_proc;
- LIN_SDT_PROBE1(emul, linux_schedtail, entry, p);
-
- /* find the emuldata */
- em = em_find(p, EMUL_DOLOCK);
-
- KASSERT(em != NULL, ("linux_schedtail: emuldata not found.\n"));
+ em = em_find(td);
+ KASSERT(em != NULL, ("linux_schedtail: thread emuldata not found.\n"));
child_set_tid = em->child_set_tid;
- EMUL_UNLOCK(&emul_lock);
if (child_set_tid != NULL) {
- error = copyout(&p->p_pid, (int *)child_set_tid,
- sizeof(p->p_pid));
-
- if (error != 0) {
- LIN_SDT_PROBE1(emul, linux_schedtail, copyout_error,
- error);
- }
- }
-
- LIN_SDT_PROBE0(emul, linux_schedtail, return);
-
- return;
-}
-
-int
-linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args)
-{
- struct linux_emuldata *em;
-
- LIN_SDT_PROBE1(emul, linux_set_tid_address, entry, args->tidptr);
-
- /* find the emuldata */
- em = em_find(td->td_proc, EMUL_DOLOCK);
-
- KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n"));
-
- em->child_clear_tid = args->tidptr;
- td->td_retval[0] = td->td_proc->p_pid;
-
- EMUL_UNLOCK(&emul_lock);
-
- LIN_SDT_PROBE0(emul, linux_set_tid_address, return);
- return 0;
-}
-
-void
-linux_kill_threads(struct thread *td, int sig)
-{
- struct linux_emuldata *em, *td_em, *tmp_em;
- struct proc *sp;
-
- LIN_SDT_PROBE2(emul, linux_kill_threads, entry, td, sig);
-
- td_em = em_find(td->td_proc, EMUL_DONTLOCK);
-
- KASSERT(td_em != NULL, ("linux_kill_threads: emuldata not found.\n"));
-
- EMUL_SHARED_RLOCK(&emul_shared_lock);
- LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) {
- if (em->pid == td_em->pid)
- continue;
-
- sp = pfind(em->pid);
- if ((sp->p_flag & P_WEXIT) == 0)
- kern_psignal(sp, sig);
- PROC_UNLOCK(sp);
-
- LIN_SDT_PROBE1(emul, linux_kill_threads, kill, em->pid);
- }
- EMUL_SHARED_RUNLOCK(&emul_shared_lock);
-
- LIN_SDT_PROBE0(emul, linux_kill_threads, return);
+ error = copyout(&em->em_tid, child_set_tid,
+ sizeof(em->em_tid));
+ LINUX_CTR4(schedtail, "thread(%d) %p stored %d error %d",
+ td->td_tid, child_set_tid, em->em_tid, error);
+ } else
+ LINUX_CTR1(schedtail, "thread(%d)", em->em_tid);
}
diff --git a/sys/compat/linux/linux_emul.h b/sys/compat/linux/linux_emul.h
index f409a34da472..726209330614 100644
--- a/sys/compat/linux/linux_emul.h
+++ b/sys/compat/linux/linux_emul.h
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2006 Roman Divacky
+ * Copyright (c) 2013 Dmitry Chagin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,91 +32,48 @@
#ifndef _LINUX_EMUL_H_
#define _LINUX_EMUL_H_
-#define EMUL_SHARED_HASXSTAT 0x01
-
-struct linux_emuldata_shared {
- int refs;
- int flags;
- int xstat;
- pid_t group_pid;
-
- LIST_HEAD(, linux_emuldata) threads; /* head of list of linux threads */
-};
-
/*
* modeled after similar structure in NetBSD
* this will be extended as we need more functionality
*/
struct linux_emuldata {
- pid_t pid;
-
int *child_set_tid; /* in clone(): Child's TID to set on clone */
int *child_clear_tid;/* in clone(): Child's TID to clear on exit */
- struct linux_emuldata_shared *shared;
-
int pdeath_signal; /* parent death signal */
- int flags; /* different emuldata flags */
+ int flags; /* thread emuldata flags */
+ int em_tid; /* thread id */
struct linux_robust_list_head *robust_futexes;
-
- LIST_ENTRY(linux_emuldata) threads; /* list of linux threads */
};
-struct linux_emuldata *em_find(struct proc *, int locked);
-
-/*
- * DTrace probes for locks should be fired after locking and before releasing
- * to prevent races (to provide data/function stability in dtrace, see the
- * output of "dtrace -v ..." and the corresponding dtrace docs).
- */
-#define EMUL_LOCK(l) do { \
- mtx_lock(l); \
- LIN_SDT_PROBE1(locks, emul_lock, \
- locked, l); \
- } while (0)
-#define EMUL_UNLOCK(l) do { \
- LIN_SDT_PROBE1(locks, emul_lock, \
- unlock, l); \
- mtx_unlock(l); \
- } while (0)
+struct linux_emuldata *em_find(struct thread *);
-#define EMUL_SHARED_RLOCK(l) do { \
- sx_slock(l); \
- LIN_SDT_PROBE1(locks, emul_shared_rlock, \
- locked, l); \
- } while (0)
-#define EMUL_SHARED_RUNLOCK(l) do { \
- LIN_SDT_PROBE1(locks, emul_shared_rlock, \
- unlock, l); \
- sx_sunlock(l); \
- } while (0)
-#define EMUL_SHARED_WLOCK(l) do { \
- sx_xlock(l); \
- LIN_SDT_PROBE1(locks, emul_shared_wlock, \
- locked, l); \
- } while (0)
-#define EMUL_SHARED_WUNLOCK(l) do { \
- LIN_SDT_PROBE1(locks, emul_shared_wlock, \
- unlock, l); \
- sx_xunlock(l); \
- } while (0)
-
-/* for em_find use */
-#define EMUL_DOLOCK 1
-#define EMUL_DONTLOCK 0
+void linux_proc_init(struct thread *, struct thread *, int);
+void linux_proc_exit(void *, struct proc *);
+void linux_schedtail(struct thread *);
+void linux_proc_exec(void *, struct proc *, struct image_params *);
+void linux_thread_dtor(void *arg __unused, struct thread *);
+void linux_thread_detach(struct thread *);
+int linux_common_execve(struct thread *, struct image_args *);
-/* emuldata flags */
+/* process emuldata flags */
#define LINUX_XDEPR_REQUEUEOP 0x00000001 /* uses deprecated
futex REQUEUE op*/
+#define LINUX_XUNSUP_EPOLL 0x00000002 /* unsupported epoll events */
+#define LINUX_XUNSUP_FUTEXPIOP 0x00000004 /* uses unsupported pi futex */
-int linux_proc_init(struct thread *, pid_t, int);
-void linux_proc_exit(void *, struct proc *);
-void linux_schedtail(struct thread *);
-void linux_proc_exec(void *, struct proc *, struct image_params *);
-void linux_kill_threads(struct thread *, int);
+struct linux_pemuldata {
+ uint32_t flags; /* process emuldata flags */
+ struct sx pem_sx; /* lock for this struct */
+ void *epoll; /* epoll data */
+};
+
+#define LINUX_PEM_XLOCK(p) sx_xlock(&(p)->pem_sx)
+#define LINUX_PEM_XUNLOCK(p) sx_xunlock(&(p)->pem_sx)
+#define LINUX_PEM_SLOCK(p) sx_slock(&(p)->pem_sx)
+#define LINUX_PEM_SUNLOCK(p) sx_sunlock(&(p)->pem_sx)
-extern struct sx emul_shared_lock;
-extern struct mtx emul_lock;
+struct linux_pemuldata *pem_find(struct proc *);
#endif /* !_LINUX_EMUL_H_ */
diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c
new file mode 100644
index 000000000000..403158823f5a
--- /dev/null
+++ b/sys/compat/linux/linux_event.c
@@ -0,0 +1,890 @@
+/*-
+ * Copyright (c) 2007 Roman Divacky
+ * Copyright (c) 2014 Dmitry Chagin
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/imgact.h>
+#include <sys/kernel.h>
+#include <sys/limits.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/capability.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/errno.h>
+#include <sys/event.h>
+#include <sys/poll.h>
+#include <sys/proc.h>
+#include <sys/selinfo.h>
+#include <sys/sx.h>
+#include <sys/syscallsubr.h>
+#include <sys/timespec.h>
+
+#ifdef COMPAT_LINUX32
+#include <machine/../linux32/linux.h>
+#include <machine/../linux32/linux32_proto.h>
+#else
+#include <machine/../linux/linux.h>
+#include <machine/../linux/linux_proto.h>
+#endif
+
+#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_event.h>
+#include <compat/linux/linux_file.h>
+#include <compat/linux/linux_util.h>
+
+/*
+ * epoll defines 'struct epoll_event' with the field 'data' as 64 bits
+ * on all architectures. But on 32 bit architectures BSD 'struct kevent' only
+ * has 32 bit opaque pointer as 'udata' field. So we can't pass epoll supplied
+ * data verbatuim. Therefore we allocate 64-bit memory block to pass
+ * user supplied data for every file descriptor.
+ */
+
+typedef uint64_t epoll_udata_t;
+
+struct epoll_emuldata {
+ uint32_t fdc; /* epoll udata max index */
+ epoll_udata_t udata[1]; /* epoll user data vector */
+};
+
+#define EPOLL_DEF_SZ 16
+#define EPOLL_SIZE(fdn) \
+ (sizeof(struct epoll_emuldata)+(fdn) * sizeof(epoll_udata_t))
+
+struct epoll_event {
+ uint32_t events;
+ epoll_udata_t data;
+}
+#if defined(__amd64__)
+__attribute__((packed))
+#endif
+;
+
+#define LINUX_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event))
+
+static void epoll_fd_install(struct thread *td, int fd, epoll_udata_t udata);
+static int epoll_to_kevent(struct thread *td, struct file *epfp,
+ int fd, struct epoll_event *l_event, int *kev_flags,
+ struct kevent *kevent, int *nkevents);
+static void kevent_to_epoll(struct kevent *kevent, struct epoll_event *l_event);
+static int epoll_kev_copyout(void *arg, struct kevent *kevp, int count);
+static int epoll_kev_copyin(void *arg, struct kevent *kevp, int count);
+static int epoll_delete_event(struct thread *td, struct file *epfp,
+ int fd, int filter);
+static int epoll_delete_all_events(struct thread *td, struct file *epfp,
+ int fd);
+
+struct epoll_copyin_args {
+ struct kevent *changelist;
+};
+
+struct epoll_copyout_args {
+ struct epoll_event *leventlist;
+ struct proc *p;
+ uint32_t count;
+ int error;
+};
+
+/* eventfd */
+typedef uint64_t eventfd_t;
+
+static fo_rdwr_t eventfd_read;
+static fo_rdwr_t eventfd_write;
+static fo_truncate_t eventfd_truncate;
+static fo_ioctl_t eventfd_ioctl;
+static fo_poll_t eventfd_poll;
+static fo_kqfilter_t eventfd_kqfilter;
+static fo_stat_t eventfd_stat;
+static fo_close_t eventfd_close;
+static fo_fill_kinfo_t eventfd_fill_kinfo;
+
+static struct fileops eventfdops = {
+ .fo_read = eventfd_read,
+ .fo_write = eventfd_write,
+ .fo_truncate = eventfd_truncate,
+ .fo_ioctl = eventfd_ioctl,
+ .fo_poll = eventfd_poll,
+ .fo_kqfilter = eventfd_kqfilter,
+ .fo_stat = eventfd_stat,
+ .fo_close = eventfd_close,
+ .fo_chmod = invfo_chmod,
+ .fo_chown = invfo_chown,
+ .fo_sendfile = invfo_sendfile,
+ .fo_fill_kinfo = eventfd_fill_kinfo,
+ .fo_flags = DFLAG_PASSABLE
+};
+
+static void filt_eventfddetach(struct knote *kn);
+static int filt_eventfdread(struct knote *kn, long hint);
+static int filt_eventfdwrite(struct knote *kn, long hint);
+
+static struct filterops eventfd_rfiltops = {
+ .f_isfd = 1,
+ .f_detach = filt_eventfddetach,
+ .f_event = filt_eventfdread
+};
+static struct filterops eventfd_wfiltops = {
+ .f_isfd = 1,
+ .f_detach = filt_eventfddetach,
+ .f_event = filt_eventfdwrite
+};
+
+struct eventfd {
+ eventfd_t efd_count;
+ uint32_t efd_flags;
+ struct selinfo efd_sel;
+ struct mtx efd_lock;
+};
+
+static int eventfd_create(struct thread *td, uint32_t initval, int flags);
+
+
+static void
+epoll_fd_install(struct thread *td, int fd, epoll_udata_t udata)
+{
+ struct linux_pemuldata *pem;
+ struct epoll_emuldata *emd;
+ struct proc *p;
+
+ p = td->td_proc;
+
+ pem = pem_find(p);
+ KASSERT(pem != NULL, ("epoll proc emuldata not found.\n"));
+
+ LINUX_PEM_XLOCK(pem);
+ if (pem->epoll == NULL) {
+ emd = malloc(EPOLL_SIZE(fd), M_EPOLL, M_WAITOK);
+ emd->fdc = fd;
+ pem->epoll = emd;
+ } else {
+ emd = pem->epoll;
+ if (fd > emd->fdc) {
+ emd = realloc(emd, EPOLL_SIZE(fd), M_EPOLL, M_WAITOK);
+ emd->fdc = fd;
+ pem->epoll = emd;
+ }
+ }
+ emd->udata[fd] = udata;
+ LINUX_PEM_XUNLOCK(pem);
+}
+
+static int
+epoll_create_common(struct thread *td, int flags)
+{
+ int error;
+
+ error = kern_kqueue(td, flags);
+ if (error)
+ return (error);
+
+ epoll_fd_install(td, EPOLL_DEF_SZ, 0);
+
+ return (0);
+}
+
+int
+linux_epoll_create(struct thread *td, struct linux_epoll_create_args *args)
+{
+
+ /*
+ * args->size is unused. Linux just tests it
+ * and then forgets it as well.
+ */
+ if (args->size <= 0)
+ return (EINVAL);
+
+ return (epoll_create_common(td, 0));
+}
+
+int
+linux_epoll_create1(struct thread *td, struct linux_epoll_create1_args *args)
+{
+ int flags;
+
+ if ((args->flags & ~(LINUX_O_CLOEXEC)) != 0)
+ return (EINVAL);
+
+ flags = 0;
+ if ((args->flags & LINUX_O_CLOEXEC) != 0)
+ flags |= O_CLOEXEC;
+
+ return (epoll_create_common(td, flags));
+}
+
+/* Structure converting function from epoll to kevent. */
+static int
+epoll_to_kevent(struct thread *td, struct file *epfp,
+ int fd, struct epoll_event *l_event, int *kev_flags,
+ struct kevent *kevent, int *nkevents)
+{
+ uint32_t levents = l_event->events;
+ struct linux_pemuldata *pem;
+ struct proc *p;
+
+ /* flags related to how event is registered */
+ if ((levents & LINUX_EPOLLONESHOT) != 0)
+ *kev_flags |= EV_ONESHOT;
+ if ((levents & LINUX_EPOLLET) != 0)
+ *kev_flags |= EV_CLEAR;
+ if ((levents & LINUX_EPOLLERR) != 0)
+ *kev_flags |= EV_ERROR;
+
+ /* flags related to what event is registered */
+ if ((levents & LINUX_EPOLL_EVRD) != 0) {
+ EV_SET(kevent++, fd, EVFILT_READ, *kev_flags, 0, 0, 0);
+ ++(*nkevents);
+ }
+ if ((levents & LINUX_EPOLL_EVWR) != 0) {
+ EV_SET(kevent++, fd, EVFILT_WRITE, *kev_flags, 0, 0, 0);
+ ++(*nkevents);
+ }
+
+ if ((levents & ~(LINUX_EPOLL_EVSUP)) != 0) {
+ p = td->td_proc;
+
+ pem = pem_find(p);
+ KASSERT(pem != NULL, ("epoll proc emuldata not found.\n"));
+ KASSERT(pem->epoll != NULL, ("epoll proc epolldata not found.\n"));
+
+ LINUX_PEM_XLOCK(pem);
+ if ((pem->flags & LINUX_XUNSUP_EPOLL) == 0) {
+ pem->flags |= LINUX_XUNSUP_EPOLL;
+ LINUX_PEM_XUNLOCK(pem);
+ linux_msg(td, "epoll_ctl unsupported flags: 0x%x\n",
+ levents);
+ } else
+ LINUX_PEM_XUNLOCK(pem);
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+/*
+ * Structure converting function from kevent to epoll. In a case
+ * this is called on error in registration we store the error in
+ * event->data and pick it up later in linux_epoll_ctl().
+ */
+static void
+kevent_to_epoll(struct kevent *kevent, struct epoll_event *l_event)
+{
+
+ if ((kevent->flags & EV_ERROR) != 0) {
+ l_event->events = LINUX_EPOLLERR;
+ return;
+ }
+
+ switch (kevent->filter) {
+ case EVFILT_READ:
+ l_event->events = LINUX_EPOLLIN|LINUX_EPOLLRDNORM|LINUX_EPOLLPRI;
+ break;
+ case EVFILT_WRITE:
+ l_event->events = LINUX_EPOLLOUT|LINUX_EPOLLWRNORM;
+ break;
+ }
+}
+
+/*
+ * Copyout callback used by kevent. This converts kevent
+ * events to epoll events and copies them back to the
+ * userspace. This is also called on error on registering
+ * of the filter.
+ */
+static int
+epoll_kev_copyout(void *arg, struct kevent *kevp, int count)
+{
+ struct epoll_copyout_args *args;
+ struct linux_pemuldata *pem;
+ struct epoll_emuldata *emd;
+ struct epoll_event *eep;
+ int error, fd, i;
+
+ args = (struct epoll_copyout_args*) arg;
+ eep = malloc(sizeof(*eep) * count, M_EPOLL, M_WAITOK | M_ZERO);
+
+ pem = pem_find(args->p);
+ KASSERT(pem != NULL, ("epoll proc emuldata not found.\n"));
+ LINUX_PEM_SLOCK(pem);
+ emd = pem->epoll;
+ KASSERT(emd != NULL, ("epoll proc epolldata not found.\n"));
+
+ for (i = 0; i < count; i++) {
+ kevent_to_epoll(&kevp[i], &eep[i]);
+
+ fd = kevp[i].ident;
+ KASSERT(fd <= emd->fdc, ("epoll user data vector"
+ " is too small.\n"));
+ eep[i].data = emd->udata[fd];
+ }
+ LINUX_PEM_SUNLOCK(pem);
+
+ error = copyout(eep, args->leventlist, count * sizeof(*eep));
+ if (error == 0) {
+ args->leventlist += count;
+ args->count += count;
+ } else if (args->error == 0)
+ args->error = error;
+
+ free(eep, M_EPOLL);
+ return (error);
+}
+
+/*
+ * Copyin callback used by kevent. This copies already
+ * converted filters from kernel memory to the kevent
+ * internal kernel memory. Hence the memcpy instead of
+ * copyin.
+ */
+static int
+epoll_kev_copyin(void *arg, struct kevent *kevp, int count)
+{
+ struct epoll_copyin_args *args;
+
+ args = (struct epoll_copyin_args*) arg;
+
+ memcpy(kevp, args->changelist, count * sizeof(*kevp));
+ args->changelist += count;
+
+ return (0);
+}
+
+/*
+ * Load epoll filter, convert it to kevent filter
+ * and load it into kevent subsystem.
+ */
+int
+linux_epoll_ctl(struct thread *td, struct linux_epoll_ctl_args *args)
+{
+ struct file *epfp, *fp;
+ struct epoll_copyin_args ciargs;
+ struct kevent kev[2];
+ struct kevent_copyops k_ops = { &ciargs,
+ NULL,
+ epoll_kev_copyin};
+ struct epoll_event le;
+ cap_rights_t rights;
+ int kev_flags;
+ int nchanges = 0;
+ int error;
+
+ if (args->op != LINUX_EPOLL_CTL_DEL) {
+ error = copyin(args->event, &le, sizeof(le));
+ if (error != 0)
+ return (error);
+ }
+
+ error = fget(td, args->epfd,
+ cap_rights_init(&rights, CAP_KQUEUE_CHANGE), &epfp);
+ if (error != 0)
+ return (error);
+ if (epfp->f_type != DTYPE_KQUEUE)
+ goto leave1;
+
+ /* Protect user data vector from incorrectly supplied fd. */
+ error = fget(td, args->fd, cap_rights_init(&rights, CAP_POLL_EVENT), &fp);
+ if (error != 0)
+ goto leave1;
+
+ /* Linux disallows spying on himself */
+ if (epfp == fp) {
+ error = EINVAL;
+ goto leave0;
+ }
+
+ ciargs.changelist = kev;
+
+ switch (args->op) {
+ case LINUX_EPOLL_CTL_MOD:
+ /*
+ * We don't memorize which events were set for this FD
+ * on this level, so just delete all we could have set:
+ * EVFILT_READ and EVFILT_WRITE, ignoring any errors
+ */
+ error = epoll_delete_all_events(td, epfp, args->fd);
+ if (error)
+ goto leave0;
+ /* FALLTHROUGH */
+
+ case LINUX_EPOLL_CTL_ADD:
+ kev_flags = EV_ADD | EV_ENABLE;
+ break;
+
+ case LINUX_EPOLL_CTL_DEL:
+ /* CTL_DEL means unregister this fd with this epoll */
+ error = epoll_delete_all_events(td, epfp, args->fd);
+ goto leave0;
+
+ default:
+ error = EINVAL;
+ goto leave0;
+ }
+
+ error = epoll_to_kevent(td, epfp, args->fd, &le, &kev_flags,
+ kev, &nchanges);
+ if (error)
+ goto leave0;
+
+ epoll_fd_install(td, args->fd, le.data);
+
+ error = kern_kevent_fp(td, epfp, nchanges, 0, &k_ops, NULL);
+
+leave0:
+ fdrop(fp, td);
+
+leave1:
+ fdrop(epfp, td);
+ return (error);
+}
+
+/*
+ * Wait for a filter to be triggered on the epoll file descriptor.
+ */
+static int
+linux_epoll_wait_common(struct thread *td, int epfd, struct epoll_event *events,
+ int maxevents, int timeout, sigset_t *uset)
+{
+ struct file *epfp;
+ struct timespec ts, *tsp;
+ cap_rights_t rights;
+ struct epoll_copyout_args coargs;
+ struct kevent_copyops k_ops = { &coargs,
+ epoll_kev_copyout,
+ NULL};
+ int error;
+
+ if (maxevents <= 0 || maxevents > LINUX_MAX_EVENTS)
+ return (EINVAL);
+
+ if (uset != NULL) {
+ error = kern_sigprocmask(td, SIG_SETMASK, uset,
+ &td->td_oldsigmask, 0);
+ if (error != 0)
+ return (error);
+ td->td_pflags |= TDP_OLDMASK;
+ /*
+ * Make sure that ast() is called on return to
+ * usermode and TDP_OLDMASK is cleared, restoring old
+ * sigmask.
+ */
+ thread_lock(td);
+ td->td_flags |= TDF_ASTPENDING;
+ thread_unlock(td);
+ }
+
+ error = fget(td, epfd,
+ cap_rights_init(&rights, CAP_KQUEUE_EVENT), &epfp);
+ if (error != 0)
+ return (error);
+
+ coargs.leventlist = events;
+ coargs.p = td->td_proc;
+ coargs.count = 0;
+ coargs.error = 0;
+
+ if (timeout != -1) {
+ if (timeout < 0) {
+ error = EINVAL;
+ goto leave;
+ }
+ /* Convert from milliseconds to timespec. */
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout % 1000) * 1000000;
+ tsp = &ts;
+ } else {
+ tsp = NULL;
+ }
+
+ error = kern_kevent_fp(td, epfp, 0, maxevents, &k_ops, tsp);
+ if (error == 0 && coargs.error != 0)
+ error = coargs.error;
+
+ /*
+ * kern_kevent might return ENOMEM which is not expected from epoll_wait.
+ * Maybe we should translate that but I don't think it matters at all.
+ */
+ if (error == 0)
+ td->td_retval[0] = coargs.count;
+leave:
+ fdrop(epfp, td);
+ return (error);
+}
+
+int
+linux_epoll_wait(struct thread *td, struct linux_epoll_wait_args *args)
+{
+
+ return (linux_epoll_wait_common(td, args->epfd, args->events,
+ args->maxevents, args->timeout, NULL));
+}
+
+int
+linux_epoll_pwait(struct thread *td, struct linux_epoll_pwait_args *args)
+{
+ sigset_t mask, *pmask;
+ l_sigset_t lmask;
+ int error;
+
+ if (args->mask != NULL) {
+ error = copyin(args->mask, &lmask, sizeof(l_sigset_t));
+ if (error != 0)
+ return (error);
+ linux_to_bsd_sigset(&lmask, &mask);
+ pmask = &mask;
+ } else
+ pmask = NULL;
+ return (linux_epoll_wait_common(td, args->epfd, args->events,
+ args->maxevents, args->timeout, pmask));
+}
+
+static int
+epoll_delete_event(struct thread *td, struct file *epfp, int fd, int filter)
+{
+ struct epoll_copyin_args ciargs;
+ struct kevent kev;
+ struct kevent_copyops k_ops = { &ciargs,
+ NULL,
+ epoll_kev_copyin};
+ int error;
+
+ ciargs.changelist = &kev;
+ EV_SET(&kev, fd, filter, EV_DELETE | EV_DISABLE, 0, 0, 0);
+
+ error = kern_kevent_fp(td, epfp, 1, 0, &k_ops, NULL);
+
+ /*
+ * here we ignore ENONT, because we don't keep track of events here
+ */
+ if (error == ENOENT)
+ error = 0;
+ return (error);
+}
+
+static int
+epoll_delete_all_events(struct thread *td, struct file *epfp, int fd)
+{
+ int error1, error2;
+
+ error1 = epoll_delete_event(td, epfp, fd, EVFILT_READ);
+ error2 = epoll_delete_event(td, epfp, fd, EVFILT_WRITE);
+
+ /* report any errors we got */
+ return (error1 == 0 ? error2 : error1);
+}
+
+static int
+eventfd_create(struct thread *td, uint32_t initval, int flags)
+{
+ struct filedesc *fdp;
+ struct eventfd *efd;
+ struct file *fp;
+ int fflags, fd, error;
+
+ fflags = 0;
+ if ((flags & LINUX_O_CLOEXEC) != 0)
+ fflags |= O_CLOEXEC;
+
+ fdp = td->td_proc->p_fd;
+ error = falloc(td, &fp, &fd, fflags);
+ if (error)
+ return (error);
+
+ efd = malloc(sizeof(*efd), M_EPOLL, M_WAITOK | M_ZERO);
+ efd->efd_flags = flags;
+ efd->efd_count = initval;
+ mtx_init(&efd->efd_lock, "eventfd", NULL, MTX_DEF);
+
+ knlist_init_mtx(&efd->efd_sel.si_note, &efd->efd_lock);
+
+ fflags = FREAD | FWRITE;
+ if ((flags & LINUX_O_NONBLOCK) != 0)
+ fflags |= FNONBLOCK;
+
+ finit(fp, fflags, DTYPE_LINUXEFD, efd, &eventfdops);
+ fdrop(fp, td);
+
+ td->td_retval[0] = fd;
+ return (error);
+}
+
+int
+linux_eventfd(struct thread *td, struct linux_eventfd_args *args)
+{
+
+ return (eventfd_create(td, args->initval, 0));
+}
+
+int
+linux_eventfd2(struct thread *td, struct linux_eventfd2_args *args)
+{
+
+ if ((args->flags & ~(LINUX_O_CLOEXEC|LINUX_O_NONBLOCK|LINUX_EFD_SEMAPHORE)) != 0)
+ return (EINVAL);
+
+ return (eventfd_create(td, args->initval, args->flags));
+}
+
+static int
+eventfd_close(struct file *fp, struct thread *td)
+{
+ struct eventfd *efd;
+
+ efd = fp->f_data;
+ if (fp->f_type != DTYPE_LINUXEFD || efd == NULL)
+ return (EBADF);
+
+ seldrain(&efd->efd_sel);
+ knlist_destroy(&efd->efd_sel.si_note);
+
+ fp->f_ops = &badfileops;
+ mtx_destroy(&efd->efd_lock);
+ free(efd, M_EPOLL);
+
+ return (0);
+}
+
+static int
+eventfd_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
+ int flags, struct thread *td)
+{
+ struct eventfd *efd;
+ eventfd_t count;
+ int error;
+
+ efd = fp->f_data;
+ if (fp->f_type != DTYPE_LINUXEFD || efd == NULL)
+ return (EBADF);
+
+ if (uio->uio_resid < sizeof(eventfd_t))
+ return (EINVAL);
+
+ error = 0;
+ mtx_lock(&efd->efd_lock);
+retry:
+ if (efd->efd_count == 0) {
+ if ((efd->efd_flags & LINUX_O_NONBLOCK) != 0) {
+ mtx_unlock(&efd->efd_lock);
+ return (EAGAIN);
+ }
+ error = mtx_sleep(&efd->efd_count, &efd->efd_lock, PCATCH, "lefdrd", 0);
+ if (error == 0)
+ goto retry;
+ }
+ if (error == 0) {
+ if ((efd->efd_flags & LINUX_EFD_SEMAPHORE) != 0) {
+ count = 1;
+ --efd->efd_count;
+ } else {
+ count = efd->efd_count;
+ efd->efd_count = 0;
+ }
+ KNOTE_LOCKED(&efd->efd_sel.si_note, 0);
+ selwakeup(&efd->efd_sel);
+ wakeup(&efd->efd_count);
+ mtx_unlock(&efd->efd_lock);
+ error = uiomove(&count, sizeof(eventfd_t), uio);
+ } else
+ mtx_unlock(&efd->efd_lock);
+
+ return (error);
+}
+
+static int
+eventfd_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
+ int flags, struct thread *td)
+{
+ struct eventfd *efd;
+ eventfd_t count;
+ int error;
+
+ efd = fp->f_data;
+ if (fp->f_type != DTYPE_LINUXEFD || efd == NULL)
+ return (EBADF);
+
+ if (uio->uio_resid < sizeof(eventfd_t))
+ return (EINVAL);
+
+ error = uiomove(&count, sizeof(eventfd_t), uio);
+ if (error)
+ return (error);
+ if (count == UINT64_MAX)
+ return (EINVAL);
+
+ mtx_lock(&efd->efd_lock);
+retry:
+ if (UINT64_MAX - efd->efd_count <= count) {
+ if ((efd->efd_flags & LINUX_O_NONBLOCK) != 0) {
+ mtx_unlock(&efd->efd_lock);
+ return (EAGAIN);
+ }
+ error = mtx_sleep(&efd->efd_count, &efd->efd_lock,
+ PCATCH, "lefdwr", 0);
+ if (error == 0)
+ goto retry;
+ }
+ if (error == 0) {
+ efd->efd_count += count;
+ KNOTE_LOCKED(&efd->efd_sel.si_note, 0);
+ selwakeup(&efd->efd_sel);
+ wakeup(&efd->efd_count);
+ }
+ mtx_unlock(&efd->efd_lock);
+
+ return (error);
+}
+
+static int
+eventfd_poll(struct file *fp, int events, struct ucred *active_cred,
+ struct thread *td)
+{
+ struct eventfd *efd;
+ int revents = 0;
+
+ efd = fp->f_data;
+ if (fp->f_type != DTYPE_LINUXEFD || efd == NULL)
+ return (POLLERR);
+
+ mtx_lock(&efd->efd_lock);
+ if ((events & (POLLIN|POLLRDNORM)) && efd->efd_count > 0)
+ revents |= events & (POLLIN|POLLRDNORM);
+ if ((events & (POLLOUT|POLLWRNORM)) && UINT64_MAX - 1 > efd->efd_count)
+ revents |= events & (POLLOUT|POLLWRNORM);
+ if (revents == 0)
+ selrecord(td, &efd->efd_sel);
+ mtx_unlock(&efd->efd_lock);
+
+ return (revents);
+}
+
+/*ARGSUSED*/
+static int
+eventfd_kqfilter(struct file *fp, struct knote *kn)
+{
+ struct eventfd *efd;
+
+ efd = fp->f_data;
+ if (fp->f_type != DTYPE_LINUXEFD || efd == NULL)
+ return (EINVAL);
+
+ mtx_lock(&efd->efd_lock);
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ kn->kn_fop = &eventfd_rfiltops;
+ break;
+ case EVFILT_WRITE:
+ kn->kn_fop = &eventfd_wfiltops;
+ break;
+ default:
+ mtx_unlock(&efd->efd_lock);
+ return (EINVAL);
+ }
+
+ kn->kn_hook = efd;
+ knlist_add(&efd->efd_sel.si_note, kn, 1);
+ mtx_unlock(&efd->efd_lock);
+
+ return (0);
+}
+
+static void
+filt_eventfddetach(struct knote *kn)
+{
+ struct eventfd *efd = kn->kn_hook;
+
+ mtx_lock(&efd->efd_lock);
+ knlist_remove(&efd->efd_sel.si_note, kn, 1);
+ mtx_unlock(&efd->efd_lock);
+}
+
+/*ARGSUSED*/
+static int
+filt_eventfdread(struct knote *kn, long hint)
+{
+ struct eventfd *efd = kn->kn_hook;
+ int ret;
+
+ mtx_assert(&efd->efd_lock, MA_OWNED);
+ ret = (efd->efd_count > 0);
+
+ return (ret);
+}
+
+/*ARGSUSED*/
+static int
+filt_eventfdwrite(struct knote *kn, long hint)
+{
+ struct eventfd *efd = kn->kn_hook;
+ int ret;
+
+ mtx_assert(&efd->efd_lock, MA_OWNED);
+ ret = (UINT64_MAX - 1 > efd->efd_count);
+
+ return (ret);
+}
+
+/*ARGSUSED*/
+static int
+eventfd_truncate(struct file *fp, off_t length, struct ucred *active_cred,
+ struct thread *td)
+{
+
+ return (ENXIO);
+}
+
+/*ARGSUSED*/
+static int
+eventfd_ioctl(struct file *fp, u_long cmd, void *data,
+ struct ucred *active_cred, struct thread *td)
+{
+
+ return (ENXIO);
+}
+
+/*ARGSUSED*/
+static int
+eventfd_stat(struct file *fp, struct stat *st, struct ucred *active_cred,
+ struct thread *td)
+{
+
+ return (ENXIO);
+}
+
+/*ARGSUSED*/
+static int
+eventfd_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
+{
+
+ kif->kf_type = KF_TYPE_UNKNOWN;
+ return (0);
+}
diff --git a/sys/compat/linux/linux_event.h b/sys/compat/linux/linux_event.h
new file mode 100644
index 000000000000..0c030adcf8fd
--- /dev/null
+++ b/sys/compat/linux/linux_event.h
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2007 Roman Divacky
+ * Copyright (c) 2014 Dmitry Chagin
+ * 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$
+ */
+
+#ifndef _LINUX_EVENT_H_
+#define _LINUX_EVENT_H_
+
+#define LINUX_EPOLLIN 0x001
+#define LINUX_EPOLLPRI 0x002
+#define LINUX_EPOLLOUT 0x004
+#define LINUX_EPOLLRDNORM 0x040
+#define LINUX_EPOLLRDBAND 0x080
+#define LINUX_EPOLLWRNORM 0x100
+#define LINUX_EPOLLWRBAND 0x200
+#define LINUX_EPOLLMSG 0x400
+#define LINUX_EPOLLERR 0x008
+#define LINUX_EPOLLHUP 0x010
+#define LINUX_EPOLLRDHUP 0x2000
+#define LINUX_EPOLLWAKEUP 1u<<29
+#define LINUX_EPOLLONESHOT 1u<<30
+#define LINUX_EPOLLET 1u<<31
+
+#define LINUX_EPOLL_EVRD (LINUX_EPOLLIN|LINUX_EPOLLRDNORM \
+ |LINUX_EPOLLHUP|LINUX_EPOLLERR|LINUX_EPOLLPRI)
+#define LINUX_EPOLL_EVWR (LINUX_EPOLLOUT|LINUX_EPOLLWRNORM)
+#define LINUX_EPOLL_EVSUP (LINUX_EPOLLET|LINUX_EPOLLONESHOT \
+ |LINUX_EPOLL_EVRD|LINUX_EPOLL_EVWR)
+
+#define LINUX_EPOLL_CTL_ADD 1
+#define LINUX_EPOLL_CTL_DEL 2
+#define LINUX_EPOLL_CTL_MOD 3
+
+#define LINUX_EFD_SEMAPHORE (1 << 0)
+
+#endif /* !_LINUX_EVENT_H_ */
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 78a65d0833bc..9251a20abad1 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -235,6 +235,7 @@ linux_lseek(struct thread *td, struct linux_lseek_args *args)
return error;
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_llseek(struct thread *td, struct linux_llseek_args *args)
{
@@ -273,6 +274,7 @@ linux_readdir(struct thread *td, struct linux_readdir_args *args)
lda.count = 1;
return linux_getdents(td, &lda);
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
/*
* Note that linux_getdents(2) and linux_getdents64(2) have the same
@@ -367,8 +369,8 @@ getdents_common(struct thread *td, struct linux_getdents64_args *args,
buflen = max(LINUX_DIRBLKSIZ, nbytes);
buflen = min(buflen, MAXBSIZE);
- buf = malloc(buflen, M_TEMP, M_WAITOK);
- lbuf = malloc(LINUX_MAXRECLEN, M_TEMP, M_WAITOK | M_ZERO);
+ buf = malloc(buflen, M_LINUX, M_WAITOK);
+ lbuf = malloc(LINUX_MAXRECLEN, M_LINUX, M_WAITOK | M_ZERO);
vn_lock(vp, LK_SHARED | LK_RETRY);
aiov.iov_base = buf;
@@ -519,8 +521,8 @@ out:
VOP_UNLOCK(vp, 0);
foffset_unlock(fp, off, 0);
fdrop(fp, td);
- free(buf, M_TEMP);
- free(lbuf, M_TEMP);
+ free(buf, M_LINUX);
+ free(lbuf, M_LINUX);
return (error);
}
@@ -579,10 +581,8 @@ int
linux_faccessat(struct thread *td, struct linux_faccessat_args *args)
{
char *path;
- int error, dfd, flag;
+ int error, dfd;
- if (args->flag & ~LINUX_AT_EACCESS)
- return (EINVAL);
/* linux convention */
if (args->amode & ~(F_OK | X_OK | W_OK | R_OK))
return (EINVAL);
@@ -595,8 +595,7 @@ linux_faccessat(struct thread *td, struct linux_faccessat_args *args)
printf(ARGS(access, "%s, %d"), path, args->amode);
#endif
- flag = (args->flag & LINUX_AT_EACCESS) == 0 ? 0 : AT_EACCESS;
- error = kern_accessat(td, dfd, path, UIO_SYSSPACE, flag, args->amode);
+ error = kern_accessat(td, dfd, path, UIO_SYSSPACE, 0, args->amode);
LFREEPATH(path);
return (error);
@@ -924,6 +923,7 @@ linux_truncate(struct thread *td, struct linux_truncate_args *args)
return (error);
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_truncate64(struct thread *td, struct linux_truncate64_args *args)
{
@@ -941,6 +941,8 @@ linux_truncate64(struct thread *td, struct linux_truncate64_args *args)
LFREEPATH(path);
return (error);
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
int
linux_ftruncate(struct thread *td, struct linux_ftruncate_args *args)
{
@@ -1129,6 +1131,7 @@ linux_mount(struct thread *td, struct linux_mount_args *args)
return (error);
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_oldumount(struct thread *td, struct linux_oldumount_args *args)
{
@@ -1138,6 +1141,7 @@ linux_oldumount(struct thread *td, struct linux_oldumount_args *args)
args2.flags = 0;
return (linux_umount(td, &args2));
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
linux_umount(struct thread *td, struct linux_umount_args *args)
@@ -1268,7 +1272,7 @@ bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock)
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
static int
-fcntl_common(struct thread *td, struct linux_fcntl64_args *args)
+fcntl_common(struct thread *td, struct linux_fcntl_args *args)
{
struct l_flock linux_flock;
struct flock bsd_flock;
@@ -1386,6 +1390,9 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args)
fdrop(fp, td);
return (kern_fcntl(td, args->fd, F_SETOWN, args->arg));
+
+ case LINUX_F_DUPFD_CLOEXEC:
+ return (kern_fcntl(td, args->fd, F_DUPFD_CLOEXEC, args->arg));
}
return (EINVAL);
@@ -1394,17 +1401,13 @@ fcntl_common(struct thread *td, struct linux_fcntl64_args *args)
int
linux_fcntl(struct thread *td, struct linux_fcntl_args *args)
{
- struct linux_fcntl64_args args64;
#ifdef DEBUG
if (ldebug(fcntl))
printf(ARGS(fcntl, "%d, %08x, *"), args->fd, args->cmd);
#endif
- args64.fd = args->fd;
- args64.cmd = args->cmd;
- args64.arg = args->arg;
- return (fcntl_common(td, &args64));
+ return (fcntl_common(td, args));
}
#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
@@ -1413,6 +1416,7 @@ linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args)
{
struct l_flock64 linux_flock;
struct flock bsd_flock;
+ struct linux_fcntl_args fcntl_args;
int error;
#ifdef DEBUG
@@ -1453,7 +1457,10 @@ linux_fcntl64(struct thread *td, struct linux_fcntl64_args *args)
(intptr_t)&bsd_flock));
}
- return (fcntl_common(td, args));
+ fcntl_args.fd = args->fd;
+ fcntl_args.cmd = args->cmd;
+ fcntl_args.arg = args->arg;
+ return (fcntl_common(td, &fcntl_args));
}
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
@@ -1551,6 +1558,7 @@ linux_fadvise64(struct thread *td, struct linux_fadvise64_args *args)
advice));
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_fadvise64_64(struct thread *td, struct linux_fadvise64_64_args *args)
{
@@ -1562,6 +1570,7 @@ linux_fadvise64_64(struct thread *td, struct linux_fadvise64_64_args *args)
return (kern_posix_fadvise(td, args->fd, args->offset, args->len,
advice));
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
linux_pipe(struct thread *td, struct linux_pipe_args *args)
@@ -1608,3 +1617,37 @@ linux_pipe2(struct thread *td, struct linux_pipe2_args *args)
/* XXX: Close descriptors on error. */
return (copyout(fildes, args->pipefds, sizeof(fildes)));
}
+
+int
+linux_dup3(struct thread *td, struct linux_dup3_args *args)
+{
+ int cmd;
+ intptr_t newfd;
+
+ if (args->oldfd == args->newfd)
+ return (EINVAL);
+ if ((args->flags & ~LINUX_O_CLOEXEC) != 0)
+ return (EINVAL);
+ if (args->flags & LINUX_O_CLOEXEC)
+ cmd = F_DUP2FD_CLOEXEC;
+ else
+ cmd = F_DUP2FD;
+
+ newfd = args->newfd;
+ return (kern_fcntl(td, args->oldfd, cmd, newfd));
+}
+
+int
+linux_fallocate(struct thread *td, struct linux_fallocate_args *args)
+{
+
+ /*
+ * We emulate only posix_fallocate system call for which
+ * mode should be 0.
+ */
+ if (args->mode != 0)
+ return (ENOSYS);
+
+ return (kern_posix_fallocate(td, args->fd, args->offset,
+ args->len));
+}
diff --git a/sys/compat/linux/linux_file.h b/sys/compat/linux/linux_file.h
index 2d3106f3403f..f27d5b41cc8d 100644
--- a/sys/compat/linux/linux_file.h
+++ b/sys/compat/linux/linux_file.h
@@ -54,4 +54,75 @@
#define LINUX_MS_NOEXEC 0x0008
#define LINUX_MS_REMOUNT 0x0020
+/*
+ * common open/fcntl flags
+ */
+#define LINUX_O_RDONLY 00000000
+#define LINUX_O_WRONLY 00000001
+#define LINUX_O_RDWR 00000002
+#define LINUX_O_ACCMODE 00000003
+#define LINUX_O_CREAT 00000100
+#define LINUX_O_EXCL 00000200
+#define LINUX_O_NOCTTY 00000400
+#define LINUX_O_TRUNC 00001000
+#define LINUX_O_APPEND 00002000
+#define LINUX_O_NONBLOCK 00004000
+#define LINUX_O_NDELAY LINUX_O_NONBLOCK
+#define LINUX_O_SYNC 00010000
+#define LINUX_FASYNC 00020000
+#define LINUX_O_DIRECT 00040000 /* Direct disk access hint */
+#define LINUX_O_LARGEFILE 00100000
+#define LINUX_O_DIRECTORY 00200000 /* Must be a directory */
+#define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */
+#define LINUX_O_NOATIME 01000000
+#define LINUX_O_CLOEXEC 02000000
+
+#define LINUX_F_DUPFD 0
+#define LINUX_F_GETFD 1
+#define LINUX_F_SETFD 2
+#define LINUX_F_GETFL 3
+#define LINUX_F_SETFL 4
+#ifndef LINUX_F_GETLK
+#define LINUX_F_GETLK 5
+#define LINUX_F_SETLK 6
+#define LINUX_F_SETLKW 7
+#endif
+#ifndef LINUX_F_SETOWN
+#define LINUX_F_SETOWN 8
+#define LINUX_F_GETOWN 9
+#endif
+#ifndef LINUX_F_SETSIG
+#define LINUX_F_SETSIG 10
+#define LINUX_F_GETSIG 11
+#endif
+#ifndef LINUX_F_SETOWN_EX
+#define LINUX_F_SETOWN_EX 15
+#define LINUX_F_GETOWN_EX 16
+#define LINUX_F_GETOWNER_UIDS 17
+#endif
+
+#define LINUX_F_SPECIFIC_BASE 1024
+
+#define LINUX_F_SETLEASE (LINUX_F_SPECIFIC_BASE + 0)
+#define LINUX_F_GETLEASE (LINUX_F_SPECIFIC_BASE + 1)
+#define LINUX_F_CANCELLK (LINUX_F_SPECIFIC_BASE + 5)
+#define LINUX_F_DUPFD_CLOEXEC (LINUX_F_SPECIFIC_BASE + 6)
+#define LINUX_F_NOTIFY (LINUX_F_SPECIFIC_BASE + 2)
+#define LINUX_F_SETPIPE_SZ (LINUX_F_SPECIFIC_BASE + 7)
+#define LINUX_F_GETPIPE_SZ (LINUX_F_SPECIFIC_BASE + 8)
+
+#define LINUX_F_GETLKP 36
+#define LINUX_F_SETLKP 37
+#define LINUX_F_SETLKPW 38
+
+#define LINUX_F_OWNER_TID 0
+#define LINUX_F_OWNER_PID 1
+#define LINUX_F_OWNER_PGRP 2
+
+#ifndef LINUX_F_RDLCK
+#define LINUX_F_RDLCK 0
+#define LINUX_F_WRLCK 1
+#define LINUX_F_UNLCK 2
+#endif
+
#endif /* !_LINUX_FILE_H_ */
diff --git a/sys/compat/linux/linux_fork.c b/sys/compat/linux/linux_fork.c
index 316cf2a61ebb..394c26fffa5f 100644
--- a/sys/compat/linux/linux_fork.c
+++ b/sys/compat/linux/linux_fork.c
@@ -34,13 +34,20 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/imgact.h>
+#include <sys/ktr.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/racct.h>
#include <sys/sched.h>
-#include <sys/sdt.h>
+#include <sys/syscallsubr.h>
#include <sys/sx.h>
#include <sys/unistd.h>
+#include <sys/wait.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
#ifdef COMPAT_LINUX32
#include <machine/../linux32/linux.h>
@@ -49,18 +56,10 @@ __FBSDID("$FreeBSD$");
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#endif
-#include <compat/linux/linux_dtrace.h>
-#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_futex.h>
#include <compat/linux/linux_misc.h>
-
-/* DTrace init */
-LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
-
-/* Linuxulator-global DTrace probes */
-LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked);
-LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock);
-
+#include <compat/linux/linux_util.h>
int
linux_fork(struct thread *td, struct linux_fork_args *args)
@@ -78,14 +77,11 @@ linux_fork(struct thread *td, struct linux_fork_args *args)
!= 0)
return (error);
- td->td_retval[0] = p2->p_pid;
- td->td_retval[1] = 0;
+ td2 = FIRST_THREAD_IN_PROC(p2);
- error = linux_proc_init(td, td->td_retval[0], 0);
- if (error)
- return (error);
+ linux_proc_init(td, td2, 0);
- td2 = FIRST_THREAD_IN_PROC(p2);
+ td->td_retval[0] = p2->p_pid;
/*
* Make this runnable after we are finished with it.
@@ -115,17 +111,16 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args)
NULL, 0)) != 0)
return (error);
- td->td_retval[0] = p2->p_pid;
- error = linux_proc_init(td, td->td_retval[0], 0);
- if (error)
- return (error);
+ td2 = FIRST_THREAD_IN_PROC(p2);
+
+ linux_proc_init(td, td2, 0);
PROC_LOCK(p2);
p2->p_flag |= P_PPWAIT;
PROC_UNLOCK(p2);
- td2 = FIRST_THREAD_IN_PROC(p2);
+ td->td_retval[0] = p2->p_pid;
/*
* Make this runnable after we are finished with it.
@@ -144,8 +139,8 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args)
return (0);
}
-int
-linux_clone(struct thread *td, struct linux_clone_args *args)
+static int
+linux_clone_proc(struct thread *td, struct linux_clone_args *args)
{
int error, ff = RFPROC | RFSTOPPED;
struct proc *p2;
@@ -163,9 +158,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
exit_signal = args->flags & 0x000000ff;
if (LINUX_SIG_VALID(exit_signal)) {
- if (exit_signal <= LINUX_SIGTBLSZ)
- exit_signal =
- linux_to_bsd_signal[_SIG_IDX(exit_signal)];
+ exit_signal = linux_to_bsd_signal(exit_signal);
} else if (exit_signal != 0)
return (EINVAL);
@@ -182,22 +175,6 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS)))
ff |= RFFDG;
- /*
- * Attempt to detect when linux_clone(2) is used for creating
- * kernel threads. Unfortunately despite the existence of the
- * CLONE_THREAD flag, version of linuxthreads package used in
- * most popular distros as of beginning of 2005 doesn't make
- * any use of it. Therefore, this detection relies on
- * empirical observation that linuxthreads sets certain
- * combination of flags, so that we can make more or less
- * precise detection and notify the FreeBSD kernel that several
- * processes are in fact part of the same threading group, so
- * that special treatment is necessary for signal delivery
- * between those processes and fd locking.
- */
- if ((args->flags & 0xffffff00) == LINUX_THREADING_FLAGS)
- ff |= RFTHREAD;
-
if (args->flags & LINUX_CLONE_PARENT_SETTID)
if (args->parent_tidptr == NULL)
return (EINVAL);
@@ -206,29 +183,13 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
if (error)
return (error);
- if (args->flags & (LINUX_CLONE_PARENT | LINUX_CLONE_THREAD)) {
- sx_xlock(&proctree_lock);
- PROC_LOCK(p2);
- proc_reparent(p2, td->td_proc->p_pptr);
- PROC_UNLOCK(p2);
- sx_xunlock(&proctree_lock);
- }
+ td2 = FIRST_THREAD_IN_PROC(p2);
/* create the emuldata */
- error = linux_proc_init(td, p2->p_pid, args->flags);
- /* reference it - no need to check this */
- em = em_find(p2, EMUL_DOLOCK);
- KASSERT(em != NULL, ("clone: emuldata not found."));
- /* and adjust it */
-
- if (args->flags & LINUX_CLONE_THREAD) {
-#ifdef notyet
- PROC_LOCK(p2);
- p2->p_pgrp = td->td_proc->p_pgrp;
- PROC_UNLOCK(p2);
-#endif
- exit_signal = 0;
- }
+ linux_proc_init(td, td2, args->flags);
+
+ em = em_find(td2);
+ KASSERT(em != NULL, ("clone_proc: emuldata not found.\n"));
if (args->flags & LINUX_CLONE_CHILD_SETTID)
em->child_set_tid = args->child_tidptr;
@@ -240,8 +201,6 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
else
em->child_clear_tid = NULL;
- EMUL_UNLOCK(&emul_lock);
-
if (args->flags & LINUX_CLONE_PARENT_SETTID) {
error = copyout(&p2->p_pid, args->parent_tidptr,
sizeof(p2->p_pid));
@@ -252,14 +211,12 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
PROC_LOCK(p2);
p2->p_sigparent = exit_signal;
PROC_UNLOCK(p2);
- td2 = FIRST_THREAD_IN_PROC(p2);
/*
* In a case of stack = NULL, we are supposed to COW calling process
* stack. This is what normal fork() does, so we just keep tf_rsp arg
* intact.
*/
- if (args->stack)
- linux_set_upcall_kse(td2, PTROUT(args->stack));
+ linux_set_upcall_kse(td2, PTROUT(args->stack));
if (args->flags & LINUX_CLONE_SETTLS)
linux_set_cloned_tls(td2, args->tls);
@@ -270,6 +227,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
"stack %p sig = %d"), (int)p2->p_pid, args->stack,
exit_signal);
#endif
+
if (args->flags & LINUX_CLONE_VFORK) {
PROC_LOCK(p2);
p2->p_flag |= P_PPWAIT;
@@ -285,7 +243,6 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
thread_unlock(td2);
td->td_retval[0] = p2->p_pid;
- td->td_retval[1] = 0;
if (args->flags & LINUX_CLONE_VFORK) {
/* wait for the children to exit, ie. emulate vfork */
@@ -297,3 +254,210 @@ linux_clone(struct thread *td, struct linux_clone_args *args)
return (0);
}
+
+static int
+linux_clone_thread(struct thread *td, struct linux_clone_args *args)
+{
+ struct linux_emuldata *em;
+ struct thread *newtd;
+ struct proc *p;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(clone)) {
+ printf(ARGS(clone, "thread: flags %x, stack %p, parent tid: %p, "
+ "child tid: %p"), (unsigned)args->flags,
+ args->stack, args->parent_tidptr, args->child_tidptr);
+ }
+#endif
+
+ LINUX_CTR4(clone_thread, "thread(%d) flags %x ptid %p ctid %p",
+ td->td_tid, (unsigned)args->flags,
+ args->parent_tidptr, args->child_tidptr);
+
+ if (args->flags & LINUX_CLONE_PARENT_SETTID)
+ if (args->parent_tidptr == NULL)
+ return (EINVAL);
+
+ /* Threads should be created with own stack */
+ if (args->stack == NULL)
+ return (EINVAL);
+
+ p = td->td_proc;
+
+ /* Initialize our td */
+ error = kern_thr_alloc(p, 0, &newtd);
+ if (error)
+ return (error);
+
+ cpu_set_upcall(newtd, td);
+
+ bzero(&newtd->td_startzero,
+ __rangeof(struct thread, td_startzero, td_endzero));
+ bcopy(&td->td_startcopy, &newtd->td_startcopy,
+ __rangeof(struct thread, td_startcopy, td_endcopy));
+
+ newtd->td_proc = p;
+ thread_cow_get(newtd, td);
+
+ /* create the emuldata */
+ linux_proc_init(td, newtd, args->flags);
+
+ em = em_find(newtd);
+ KASSERT(em != NULL, ("clone_thread: emuldata not found.\n"));
+
+ if (args->flags & LINUX_CLONE_SETTLS)
+ linux_set_cloned_tls(newtd, args->tls);
+
+ if (args->flags & LINUX_CLONE_CHILD_SETTID)
+ em->child_set_tid = args->child_tidptr;
+ else
+ em->child_set_tid = NULL;
+
+ if (args->flags & LINUX_CLONE_CHILD_CLEARTID)
+ em->child_clear_tid = args->child_tidptr;
+ else
+ em->child_clear_tid = NULL;
+
+ cpu_thread_clean(newtd);
+
+ linux_set_upcall_kse(newtd, PTROUT(args->stack));
+
+ PROC_LOCK(p);
+ p->p_flag |= P_HADTHREADS;
+ bcopy(p->p_comm, newtd->td_name, sizeof(newtd->td_name));
+
+ if (args->flags & LINUX_CLONE_PARENT)
+ thread_link(newtd, p->p_pptr);
+ else
+ thread_link(newtd, p);
+
+ thread_lock(td);
+ /* let the scheduler know about these things. */
+ sched_fork_thread(td, newtd);
+ thread_unlock(td);
+ if (P_SHOULDSTOP(p))
+ newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK;
+ PROC_UNLOCK(p);
+
+ tidhash_add(newtd);
+
+#ifdef DEBUG
+ if (ldebug(clone))
+ printf(ARGS(clone, "successful clone to %d, stack %p"),
+ (int)newtd->td_tid, args->stack);
+#endif
+
+ LINUX_CTR2(clone_thread, "thread(%d) successful clone to %d",
+ td->td_tid, newtd->td_tid);
+
+ if (args->flags & LINUX_CLONE_PARENT_SETTID) {
+ error = copyout(&newtd->td_tid, args->parent_tidptr,
+ sizeof(newtd->td_tid));
+ if (error)
+ printf(LMSG("clone_thread: copyout failed!"));
+ }
+
+ /*
+ * Make this runnable after we are finished with it.
+ */
+ thread_lock(newtd);
+ TD_SET_CAN_RUN(newtd);
+ sched_add(newtd, SRQ_BORING);
+ thread_unlock(newtd);
+
+ td->td_retval[0] = newtd->td_tid;
+
+ return (0);
+}
+
+int
+linux_clone(struct thread *td, struct linux_clone_args *args)
+{
+
+ if (args->flags & LINUX_CLONE_THREAD)
+ return (linux_clone_thread(td, args));
+ else
+ return (linux_clone_proc(td, args));
+}
+
+int
+linux_exit(struct thread *td, struct linux_exit_args *args)
+{
+ struct linux_emuldata *em;
+
+ em = em_find(td);
+ KASSERT(em != NULL, ("exit: emuldata not found.\n"));
+
+ LINUX_CTR2(exit, "thread(%d) (%d)", em->em_tid, args->rval);
+
+ linux_thread_detach(td);
+
+ /*
+ * XXX. When the last two threads of a process
+ * exit via pthread_exit() try thr_exit() first.
+ */
+ kern_thr_exit(td);
+ exit1(td, W_EXITCODE(args->rval, 0));
+ /* NOTREACHED */
+}
+
+int
+linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args)
+{
+ struct linux_emuldata *em;
+
+ em = em_find(td);
+ KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n"));
+
+ em->child_clear_tid = args->tidptr;
+
+ td->td_retval[0] = em->em_tid;
+
+ LINUX_CTR3(set_tid_address, "tidptr(%d) %p, returns %d",
+ em->em_tid, args->tidptr, td->td_retval[0]);
+
+ return (0);
+}
+
+void
+linux_thread_detach(struct thread *td)
+{
+ struct linux_sys_futex_args cup;
+ struct linux_emuldata *em;
+ int *child_clear_tid;
+ int error;
+
+ em = em_find(td);
+ KASSERT(em != NULL, ("thread_detach: emuldata not found.\n"));
+
+ LINUX_CTR1(thread_detach, "thread(%d)", em->em_tid);
+
+ release_futexes(td, em);
+
+ child_clear_tid = em->child_clear_tid;
+
+ if (child_clear_tid != NULL) {
+
+ LINUX_CTR2(thread_detach, "thread(%d) %p",
+ em->em_tid, child_clear_tid);
+
+ error = suword32(child_clear_tid, 0);
+ if (error != 0)
+ return;
+
+ cup.uaddr = child_clear_tid;
+ cup.op = LINUX_FUTEX_WAKE;
+ cup.val = 1; /* wake one */
+ cup.timeout = NULL;
+ cup.uaddr2 = NULL;
+ cup.val3 = 0;
+ error = linux_sys_futex(td, &cup);
+ /*
+ * this cannot happen at the moment and if this happens it
+ * probably means there is a user space bug
+ */
+ if (error != 0)
+ linux_msg(td, "futex stuff in thread_detach failed.");
+ }
+}
diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c
index 3a0952b13d37..84fc996e95bf 100644
--- a/sys/compat/linux/linux_futex.c
+++ b/sys/compat/linux/linux_futex.c
@@ -65,15 +65,12 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.7 2006/07/24 19:01:49 manu Exp $")
#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_futex.h>
+#include <compat/linux/linux_timer.h>
#include <compat/linux/linux_util.h>
/* DTrace init */
LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
-/* Linuxulator-global DTrace probes */
-LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked);
-LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock);
-
/**
* Futex part for the special DTrace module "locks".
*/
@@ -174,8 +171,8 @@ LIN_SDT_PROBE_DEFINE2(futex, linux_get_robust_list, entry, "struct thread *",
"struct linux_get_robust_list_args *");
LIN_SDT_PROBE_DEFINE1(futex, linux_get_robust_list, copyout_error, "int");
LIN_SDT_PROBE_DEFINE1(futex, linux_get_robust_list, return, "int");
-LIN_SDT_PROBE_DEFINE3(futex, handle_futex_death, entry, "struct proc *",
- "uint32_t *", "unsigned int");
+LIN_SDT_PROBE_DEFINE3(futex, handle_futex_death, entry,
+ "struct linux_emuldata *", "uint32_t *", "unsigned int");
LIN_SDT_PROBE_DEFINE1(futex, handle_futex_death, copyin_error, "int");
LIN_SDT_PROBE_DEFINE1(futex, handle_futex_death, return, "int");
LIN_SDT_PROBE_DEFINE3(futex, fetch_robust_entry, entry,
@@ -183,13 +180,11 @@ LIN_SDT_PROBE_DEFINE3(futex, fetch_robust_entry, entry,
"unsigned int *");
LIN_SDT_PROBE_DEFINE1(futex, fetch_robust_entry, copyin_error, "int");
LIN_SDT_PROBE_DEFINE1(futex, fetch_robust_entry, return, "int");
-LIN_SDT_PROBE_DEFINE1(futex, release_futexes, entry, "struct proc *");
+LIN_SDT_PROBE_DEFINE2(futex, release_futexes, entry, "struct thread *",
+ "struct linux_emuldata *");
LIN_SDT_PROBE_DEFINE1(futex, release_futexes, copyin_error, "int");
LIN_SDT_PROBE_DEFINE0(futex, release_futexes, return);
-static MALLOC_DEFINE(M_FUTEX, "futex", "Linux futexes");
-static MALLOC_DEFINE(M_FUTEX_WP, "futex wp", "Linux futexes wp");
-
struct futex;
struct waiting_proc {
@@ -252,6 +247,21 @@ struct mtx futex_mtx; /* protects the futex list */
* wp_list to prevent double wakeup.
*/
+static void futex_put(struct futex *, struct waiting_proc *);
+static int futex_get0(uint32_t *, struct futex **f, uint32_t);
+static int futex_get(uint32_t *, struct waiting_proc **, struct futex **,
+ uint32_t);
+static int futex_sleep(struct futex *, struct waiting_proc *, int);
+static int futex_wake(struct futex *, int, uint32_t);
+static int futex_requeue(struct futex *, int, struct futex *, int);
+static int futex_wait(struct futex *, struct waiting_proc *, int,
+ uint32_t);
+static int futex_atomic_op(struct thread *, int, uint32_t *);
+static int handle_futex_death(struct linux_emuldata *, uint32_t *,
+ unsigned int);
+static int fetch_robust_entry(struct linux_robust_list **,
+ struct linux_robust_list **, unsigned int *);
+
/* support.s */
int futex_xchgl(int oparg, uint32_t *uaddr, int *oldval);
int futex_addl(int oparg, uint32_t *uaddr, int *oldval);
@@ -259,6 +269,7 @@ int futex_orl(int oparg, uint32_t *uaddr, int *oldval);
int futex_andl(int oparg, uint32_t *uaddr, int *oldval);
int futex_xorl(int oparg, uint32_t *uaddr, int *oldval);
+
static void
futex_put(struct futex *f, struct waiting_proc *wp)
{
@@ -656,10 +667,11 @@ int
linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
{
int clockrt, nrwake, op_ret, ret;
- struct linux_emuldata *em;
+ struct linux_pemuldata *pem;
struct waiting_proc *wp;
struct futex *f, *f2;
- struct l_timespec timeout;
+ struct l_timespec ltimeout;
+ struct timespec timeout;
struct timeval utv, ctv;
int timeout_hz;
int error;
@@ -703,6 +715,38 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
LINUX_CTR3(sys_futex, "WAIT uaddr %p val 0x%x bitset 0x%x",
args->uaddr, args->val, args->val3);
+ if (args->timeout != NULL) {
+ error = copyin(args->timeout, &ltimeout, sizeof(ltimeout));
+ if (error) {
+ LIN_SDT_PROBE1(futex, linux_sys_futex, copyin_error,
+ error);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
+ return (error);
+ }
+ error = linux_to_native_timespec(&timeout, &ltimeout);
+ if (error)
+ return (error);
+ TIMESPEC_TO_TIMEVAL(&utv, &timeout);
+ error = itimerfix(&utv);
+ if (error) {
+ LIN_SDT_PROBE1(futex, linux_sys_futex, itimerfix_error,
+ error);
+ LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
+ return (error);
+ }
+ if (clockrt) {
+ microtime(&ctv);
+ timevalsub(&utv, &ctv);
+ } else if (args->op == LINUX_FUTEX_WAIT_BITSET) {
+ microuptime(&ctv);
+ timevalsub(&utv, &ctv);
+ }
+ if (utv.tv_sec < 0)
+ timevalclear(&utv);
+ timeout_hz = tvtohz(&utv);
+ } else
+ timeout_hz = 0;
+
error = futex_get(args->uaddr, &wp, &f,
flags | FUTEX_CREATE_WP);
if (error) {
@@ -735,37 +779,6 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
return (EWOULDBLOCK);
}
- if (args->timeout != NULL) {
- error = copyin(args->timeout, &timeout, sizeof(timeout));
- if (error) {
- LIN_SDT_PROBE1(futex, linux_sys_futex, copyin_error,
- error);
- LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
- futex_put(f, wp);
- return (error);
- }
- TIMESPEC_TO_TIMEVAL(&utv, &timeout);
- error = itimerfix(&utv);
- if (error) {
- LIN_SDT_PROBE1(futex, linux_sys_futex, itimerfix_error,
- error);
- LIN_SDT_PROBE1(futex, linux_sys_futex, return, error);
- futex_put(f, wp);
- return (error);
- }
- if (clockrt) {
- microtime(&ctv);
- timevalsub(&utv, &ctv);
- } else if (args->op == LINUX_FUTEX_WAIT_BITSET) {
- microuptime(&ctv);
- timevalsub(&utv, &ctv);
- }
- if (utv.tv_sec < 0)
- timevalclear(&utv);
- timeout_hz = tvtohz(&utv);
- } else
- timeout_hz = 0;
-
error = futex_wait(f, wp, timeout_hz, args->val3);
break;
@@ -942,29 +955,43 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
case LINUX_FUTEX_LOCK_PI:
/* not yet implemented */
- linux_msg(td,
- "linux_sys_futex: "
- "op LINUX_FUTEX_LOCK_PI not implemented\n");
- LIN_SDT_PROBE0(futex, linux_sys_futex, unimplemented_lock_pi);
+ pem = pem_find(td->td_proc);
+ if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) {
+ linux_msg(td,
+ "linux_sys_futex: "
+ "unsupported futex_pi op\n");
+ pem->flags |= LINUX_XUNSUP_FUTEXPIOP;
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_lock_pi);
+ }
LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
case LINUX_FUTEX_UNLOCK_PI:
/* not yet implemented */
- linux_msg(td,
- "linux_sys_futex: "
- "op LINUX_FUTEX_UNLOCK_PI not implemented\n");
- LIN_SDT_PROBE0(futex, linux_sys_futex, unimplemented_unlock_pi);
+ pem = pem_find(td->td_proc);
+ if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) {
+ linux_msg(td,
+ "linux_sys_futex: "
+ "unsupported futex_pi op\n");
+ pem->flags |= LINUX_XUNSUP_FUTEXPIOP;
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_unlock_pi);
+ }
LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
case LINUX_FUTEX_TRYLOCK_PI:
/* not yet implemented */
- linux_msg(td,
- "linux_sys_futex: "
- "op LINUX_FUTEX_TRYLOCK_PI not implemented\n");
- LIN_SDT_PROBE0(futex, linux_sys_futex,
- unimplemented_trylock_pi);
+ pem = pem_find(td->td_proc);
+ if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) {
+ linux_msg(td,
+ "linux_sys_futex: "
+ "unsupported futex_pi op\n");
+ pem->flags |= LINUX_XUNSUP_FUTEXPIOP;
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_trylock_pi);
+ }
LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
@@ -976,12 +1003,12 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
* Glibc versions prior to 2.3.3 fall back to FUTEX_WAKE when
* FUTEX_REQUEUE returned EINVAL.
*/
- em = em_find(td->td_proc, EMUL_DONTLOCK);
- if ((em->flags & LINUX_XDEPR_REQUEUEOP) == 0) {
+ pem = pem_find(td->td_proc);
+ if ((pem->flags & LINUX_XDEPR_REQUEUEOP) == 0) {
linux_msg(td,
"linux_sys_futex: "
"unsupported futex_requeue op\n");
- em->flags |= LINUX_XDEPR_REQUEUEOP;
+ pem->flags |= LINUX_XDEPR_REQUEUEOP;
LIN_SDT_PROBE0(futex, linux_sys_futex,
deprecated_requeue);
}
@@ -991,21 +1018,29 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args)
case LINUX_FUTEX_WAIT_REQUEUE_PI:
/* not yet implemented */
- linux_msg(td,
- "linux_sys_futex: "
- "op FUTEX_WAIT_REQUEUE_PI not implemented\n");
- LIN_SDT_PROBE0(futex, linux_sys_futex,
- unimplemented_wait_requeue_pi);
+ pem = pem_find(td->td_proc);
+ if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) {
+ linux_msg(td,
+ "linux_sys_futex: "
+ "unsupported futex_pi op\n");
+ pem->flags |= LINUX_XUNSUP_FUTEXPIOP;
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_wait_requeue_pi);
+ }
LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
case LINUX_FUTEX_CMP_REQUEUE_PI:
/* not yet implemented */
- linux_msg(td,
- "linux_sys_futex: "
- "op LINUX_FUTEX_CMP_REQUEUE_PI not implemented\n");
- LIN_SDT_PROBE0(futex, linux_sys_futex,
- unimplemented_cmp_requeue_pi);
+ pem = pem_find(td->td_proc);
+ if ((pem->flags & LINUX_XUNSUP_FUTEXPIOP) == 0) {
+ linux_msg(td,
+ "linux_sys_futex: "
+ "unsupported futex_pi op\n");
+ pem->flags |= LINUX_XUNSUP_FUTEXPIOP;
+ LIN_SDT_PROBE0(futex, linux_sys_futex,
+ unimplemented_cmp_requeue_pi);
+ }
LIN_SDT_PROBE1(futex, linux_sys_futex, return, ENOSYS);
return (ENOSYS);
@@ -1035,9 +1070,8 @@ linux_set_robust_list(struct thread *td, struct linux_set_robust_list_args *args
return (EINVAL);
}
- em = em_find(td->td_proc, EMUL_DOLOCK);
+ em = em_find(td);
em->robust_futexes = args->head;
- EMUL_UNLOCK(&emul_lock);
LIN_SDT_PROBE1(futex, linux_set_robust_list, return, 0);
return (0);
@@ -1049,29 +1083,30 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args
struct linux_emuldata *em;
struct linux_robust_list_head *head;
l_size_t len = sizeof(struct linux_robust_list_head);
+ struct thread *td2;
int error = 0;
LIN_SDT_PROBE2(futex, linux_get_robust_list, entry, td, args);
if (!args->pid) {
- em = em_find(td->td_proc, EMUL_DONTLOCK);
+ em = em_find(td);
+ KASSERT(em != NULL, ("get_robust_list: emuldata notfound.\n"));
head = em->robust_futexes;
} else {
- struct proc *p;
-
- p = pfind(args->pid);
- if (p == NULL) {
+ td2 = tdfind(args->pid, -1);
+ if (td2 == NULL) {
LIN_SDT_PROBE1(futex, linux_get_robust_list, return,
ESRCH);
return (ESRCH);
}
- em = em_find(p, EMUL_DONTLOCK);
+ em = em_find(td2);
+ KASSERT(em != NULL, ("get_robust_list: emuldata notfound.\n"));
/* XXX: ptrace? */
if (priv_check(td, PRIV_CRED_SETUID) ||
priv_check(td, PRIV_CRED_SETEUID) ||
- p_candebug(td, p)) {
- PROC_UNLOCK(p);
+ p_candebug(td, td2->td_proc)) {
+ PROC_UNLOCK(td2->td_proc);
LIN_SDT_PROBE1(futex, linux_get_robust_list, return,
EPERM);
@@ -1079,7 +1114,7 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args
}
head = em->robust_futexes;
- PROC_UNLOCK(p);
+ PROC_UNLOCK(td2->td_proc);
}
error = copyout(&len, args->len, sizeof(l_size_t));
@@ -1101,13 +1136,14 @@ linux_get_robust_list(struct thread *td, struct linux_get_robust_list_args *args
}
static int
-handle_futex_death(struct proc *p, uint32_t *uaddr, unsigned int pi)
+handle_futex_death(struct linux_emuldata *em, uint32_t *uaddr,
+ unsigned int pi)
{
uint32_t uval, nval, mval;
struct futex *f;
int error;
- LIN_SDT_PROBE3(futex, handle_futex_death, entry, p, uaddr, pi);
+ LIN_SDT_PROBE3(futex, handle_futex_death, entry, em, uaddr, pi);
retry:
error = copyin(uaddr, &uval, 4);
@@ -1116,7 +1152,7 @@ retry:
LIN_SDT_PROBE1(futex, handle_futex_death, return, EFAULT);
return (EFAULT);
}
- if ((uval & FUTEX_TID_MASK) == p->p_pid) {
+ if ((uval & FUTEX_TID_MASK) == em->em_tid) {
mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED;
nval = casuword32(uaddr, uval, mval);
@@ -1173,18 +1209,16 @@ fetch_robust_entry(struct linux_robust_list **entry,
/* This walks the list of robust futexes releasing them. */
void
-release_futexes(struct proc *p)
+release_futexes(struct thread *td, struct linux_emuldata *em)
{
struct linux_robust_list_head *head = NULL;
struct linux_robust_list *entry, *next_entry, *pending;
unsigned int limit = 2048, pi, next_pi, pip;
- struct linux_emuldata *em;
l_long futex_offset;
int rc, error;
- LIN_SDT_PROBE1(futex, release_futexes, entry, p);
+ LIN_SDT_PROBE2(futex, release_futexes, entry, td, em);
- em = em_find(p, EMUL_DONTLOCK);
head = em->robust_futexes;
if (head == NULL) {
@@ -1214,7 +1248,7 @@ release_futexes(struct proc *p)
rc = fetch_robust_entry(&next_entry, PTRIN(&entry->next), &next_pi);
if (entry != pending)
- if (handle_futex_death(p,
+ if (handle_futex_death(em,
(uint32_t *)((caddr_t)entry + futex_offset), pi)) {
LIN_SDT_PROBE0(futex, release_futexes, return);
return;
@@ -1234,7 +1268,7 @@ release_futexes(struct proc *p)
}
if (pending)
- handle_futex_death(p, (uint32_t *)((caddr_t)pending + futex_offset), pip);
+ handle_futex_death(em, (uint32_t *)((caddr_t)pending + futex_offset), pip);
LIN_SDT_PROBE0(futex, release_futexes, return);
}
diff --git a/sys/compat/linux/linux_futex.h b/sys/compat/linux/linux_futex.h
index 0990daa124e3..792274313de5 100644
--- a/sys/compat/linux/linux_futex.h
+++ b/sys/compat/linux/linux_futex.h
@@ -76,6 +76,7 @@ extern struct mtx futex_mtx;
#define FUTEX_TID_MASK 0x3fffffff
#define FUTEX_BITSET_MATCH_ANY 0xffffffff
-void release_futexes(struct proc *);
+void release_futexes(struct thread *,
+ struct linux_emuldata *);
#endif /* !_LINUX_FUTEX_H */
diff --git a/sys/compat/linux/linux_getcwd.c b/sys/compat/linux/linux_getcwd.c
index ebcf97008bf7..e6be015a4094 100644
--- a/sys/compat/linux/linux_getcwd.c
+++ b/sys/compat/linux/linux_getcwd.c
@@ -74,7 +74,7 @@ linux_getcwd(struct thread *td, struct linux_getcwd_args *args)
if (args->bufsize < 2)
return (ERANGE);
- path = malloc(LINUX_PATH_MAX, M_TEMP, M_WAITOK);
+ path = malloc(LINUX_PATH_MAX, M_LINUX, M_WAITOK);
error = kern___getcwd(td, path, UIO_SYSSPACE, args->bufsize,
LINUX_PATH_MAX);
@@ -85,6 +85,6 @@ linux_getcwd(struct thread *td, struct linux_getcwd_args *args)
td->td_retval[0] = lenused;
}
- free(path, M_TEMP);
+ free(path, M_LINUX);
return (error);
}
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 0148fec97be5..572060e8f052 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -69,7 +69,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_types.h>
-#include <net/vnet.h>
#include <dev/usb/usb_ioctl.h>
@@ -96,9 +95,6 @@ __FBSDID("$FreeBSD$");
CTASSERT(LINUX_IFNAMSIZ == IFNAMSIZ);
-FEATURE(linuxulator_v4l, "V4L ioctl wrapper support in the linuxulator");
-FEATURE(linuxulator_v4l2, "V4L2 ioctl wrapper support in the linuxulator");
-
static linux_ioctl_function_t linux_ioctl_cdrom;
static linux_ioctl_function_t linux_ioctl_vfat;
static linux_ioctl_function_t linux_ioctl_console;
@@ -1981,8 +1977,6 @@ linux_ioctl_sound(struct thread *td, struct linux_ioctl_args *args)
* Console related ioctls
*/
-#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
-
static int
linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
{
@@ -2065,8 +2059,16 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
struct vt_mode mode;
if ((error = copyin((void *)args->arg, &mode, sizeof(mode))))
break;
- if (!ISSIGVALID(mode.frsig) && ISSIGVALID(mode.acqsig))
- mode.frsig = mode.acqsig;
+ if (LINUX_SIG_VALID(mode.relsig))
+ mode.relsig = linux_to_bsd_signal(mode.relsig);
+ else
+ mode.relsig = 0;
+ if (LINUX_SIG_VALID(mode.acqsig))
+ mode.acqsig = linux_to_bsd_signal(mode.acqsig);
+ else
+ mode.acqsig = 0;
+ /* XXX. Linux ignores frsig and set it to 0. */
+ mode.frsig = 0;
if ((error = copyout(&mode, (void *)args->arg, sizeof(mode))))
break;
args->cmd = VT_SETMODE;
@@ -2109,34 +2111,6 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
#define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER)
/*
- * Interface function used by linprocfs (at the time of writing). It's not
- * used by the Linuxulator itself.
- */
-int
-linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen)
-{
- struct ifnet *ifscan;
- int ethno;
-
- IFNET_RLOCK_ASSERT();
-
- /* Short-circuit non ethernet interfaces */
- if (!IFP_IS_ETH(ifp))
- return (strlcpy(buffer, ifp->if_xname, buflen));
-
- /* Determine the (relative) unit number for ethernet interfaces */
- ethno = 0;
- TAILQ_FOREACH(ifscan, &V_ifnet, if_link) {
- if (ifscan == ifp)
- return (snprintf(buffer, buflen, "eth%d", ethno));
- if (IFP_IS_ETH(ifscan))
- ethno++;
- }
-
- return (0);
-}
-
-/*
* Translate a Linux interface name to a FreeBSD interface name,
* and return the associated ifnet structure
* bsdname and lxname need to be least IFNAMSIZ bytes long, but
@@ -3622,9 +3596,16 @@ linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
sx_sunlock(&linux_ioctl_sx);
fdrop(fp, td);
- linux_msg(td, "ioctl fd=%d, cmd=0x%x ('%c',%d) is not implemented",
- args->fd, (int)(args->cmd & 0xffff),
- (int)(args->cmd & 0xff00) >> 8, (int)(args->cmd & 0xff));
+ switch (args->cmd & 0xffff) {
+ case LINUX_BTRFS_IOC_CLONE:
+ return (ENOTSUP);
+
+ default:
+ linux_msg(td, "ioctl fd=%d, cmd=0x%x ('%c',%d) is not implemented",
+ args->fd, (int)(args->cmd & 0xffff),
+ (int)(args->cmd & 0xff00) >> 8, (int)(args->cmd & 0xff));
+ break;
+ }
return (EINVAL);
}
diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h
index 3f63b210d05e..873937deecd1 100644
--- a/sys/compat/linux/linux_ioctl.h
+++ b/sys/compat/linux/linux_ioctl.h
@@ -581,13 +581,6 @@
#define LINUX_IOCTL_DRM_MAX 0x64ff
/*
- * This doesn't really belong here, but I can't think of a better
- * place to put it.
- */
-struct ifnet;
-int linux_ifname(struct ifnet *, char *, size_t);
-
-/*
* video
*/
#define LINUX_VIDIOCGCAP 0x7601
@@ -752,6 +745,12 @@ int linux_ifname(struct ifnet *, char *, size_t);
#define FBSD_LUSB_MIN 0xffdd
/*
+ * Linux btrfs clone operation
+ */
+#define LINUX_BTRFS_IOC_CLONE 0x9409 /* 0x40049409 */
+
+
+/*
* Pluggable ioctl handlers
*/
struct linux_ioctl_args;
diff --git a/sys/compat/linux/linux_ipc.c b/sys/compat/linux/linux_ipc.c
index 1237edc65316..7a92c6ae0e11 100644
--- a/sys/compat/linux/linux_ipc.c
+++ b/sys/compat/linux/linux_ipc.c
@@ -117,16 +117,6 @@ bsd_to_linux_shm_info( struct shm_info *bpp, struct l_shm_info *lpp)
lpp->swap_successes = bpp->swap_successes ;
}
-struct l_ipc_perm {
- l_key_t key;
- l_uid16_t uid;
- l_gid16_t gid;
- l_uid16_t cuid;
- l_gid16_t cgid;
- l_ushort mode;
- l_ushort seq;
-};
-
static void
linux_to_bsd_ipc_perm(struct l_ipc_perm *lpp, struct ipc_perm *bpp)
{
diff --git a/sys/compat/linux/linux_ipc.h b/sys/compat/linux/linux_ipc.h
index f1531ba18373..8e9c050db9c7 100644
--- a/sys/compat/linux/linux_ipc.h
+++ b/sys/compat/linux/linux_ipc.h
@@ -82,7 +82,7 @@
#define LINUX_IPC_64 0x0100 /* New version (support 32-bit UIDs, bigger
message sizes, etc. */
-#if defined(__i386__) || defined(__amd64__)
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
struct linux_msgctl_args
{
@@ -177,6 +177,6 @@ int linux_shmctl(struct thread *, struct linux_shmctl_args *);
int linux_shmdt(struct thread *, struct linux_shmdt_args *);
int linux_shmget(struct thread *, struct linux_shmget_args *);
-#endif /* __i386__ || __amd64__ */
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
#endif /* _LINUX_IPC_H_ */
diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c
index 8f8cb81b48b6..396344b78864 100644
--- a/sys/compat/linux/linux_mib.c
+++ b/sys/compat/linux/linux_mib.c
@@ -29,8 +29,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "opt_compat.h"
-
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/sdt.h>
@@ -41,85 +39,11 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/jail.h>
#include <sys/lock.h>
-#include <sys/mutex.h>
#include <sys/sx.h>
-#ifdef COMPAT_LINUX32
-#include <machine/../linux32/linux.h>
-#else
-#include <machine/../linux/linux.h>
-#endif
-#include <compat/linux/linux_dtrace.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
-/* DTrace init */
-LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
-
-/**
- * DTrace probes in this module.
- */
-LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_osname, entry);
-LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osname, sysctl_string_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osname, return, "int");
-
-LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_osrelease, entry);
-LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osrelease, sysctl_string_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_osrelease, return, "int");
-LIN_SDT_PROBE_DEFINE0(mib, linux_sysctl_oss_version, entry);
-LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_oss_version, sysctl_string_error,
- "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_sysctl_oss_version, return, "int");
-LIN_SDT_PROBE_DEFINE2(mib, linux_map_osrel, entry, "char *", "int *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_map_osrel, return, "int");
-LIN_SDT_PROBE_DEFINE2(mib, linux_get_prison, entry, "struct prison *",
- "struct prison **");
-LIN_SDT_PROBE_DEFINE1(mib, linux_get_prison, return, "struct linux_prison *");
-LIN_SDT_PROBE_DEFINE2(mib, linux_alloc_prison, entry, "struct prison *",
- "struct linux_prison **");
-LIN_SDT_PROBE_DEFINE1(mib, linux_alloc_prison, return, "int");
-LIN_SDT_PROBE_DEFINE2(mib, linux_prison_create, entry, "void *", "void *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_create, vfs_copyopt_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_create, return, "int");
-LIN_SDT_PROBE_DEFINE2(mib, linux_prison_check, entry, "void *", "void *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, vfs_copyopt_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, vfs_getopt_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_check, return, "int");
-LIN_SDT_PROBE_DEFINE2(mib, linux_prison_set, entry, "void *", "void *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, vfs_copyopt_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, vfs_getopt_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_set, return, "int");
-LIN_SDT_PROBE_DEFINE2(mib, linux_prison_get, entry, "void *", "void *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, vfs_setopt_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, vfs_setopts_error, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_get, return, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_prison_destructor, entry, "void *");
-LIN_SDT_PROBE_DEFINE0(mib, linux_prison_destructor, return);
-LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_register, entry);
-LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_register, return);
-LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_deregister, entry);
-LIN_SDT_PROBE_DEFINE0(mib, linux_osd_jail_deregister, return);
-LIN_SDT_PROBE_DEFINE2(mib, linux_get_osname, entry, "struct thread *",
- "char *");
-LIN_SDT_PROBE_DEFINE0(mib, linux_get_osname, return);
-LIN_SDT_PROBE_DEFINE2(mib, linux_set_osname, entry, "struct thread *",
- "char *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_set_osname, return, "int");
-LIN_SDT_PROBE_DEFINE2(mib, linux_get_osrelease, entry, "struct thread *",
- "char *");
-LIN_SDT_PROBE_DEFINE0(mib, linux_get_osrelease, return);
-LIN_SDT_PROBE_DEFINE1(mib, linux_kernver, entry, "struct thread *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_kernver, return, "int");
-LIN_SDT_PROBE_DEFINE2(mib, linux_set_osrelease, entry, "struct thread *",
- "char *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_set_osrelease, return, "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_get_oss_version, entry, "struct thread *");
-LIN_SDT_PROBE_DEFINE1(mib, linux_get_oss_version, return, "int");
-
-LIN_SDT_PROBE_DEFINE2(mib, linux_set_oss_version, entry, "struct thread *",
- "int");
-LIN_SDT_PROBE_DEFINE1(mib, linux_set_oss_version, return, "int");
-
struct linux_prison {
char pr_osname[LINUX_MAX_UTSNAME];
char pr_osrelease[LINUX_MAX_UTSNAME];
@@ -129,15 +53,14 @@ struct linux_prison {
static struct linux_prison lprison0 = {
.pr_osname = "Linux",
- .pr_osrelease = "2.6.18",
+ .pr_osrelease = LINUX_VERSION_STR,
.pr_oss_version = 0x030600,
- .pr_osrel = 2006018
+ .pr_osrel = LINUX_VERSION_CODE
};
static unsigned linux_osd_jail_slot;
-static SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0,
- "Linux mode");
+SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, "Linux mode");
static int linux_set_osname(struct thread *td, char *osname);
static int linux_set_osrelease(struct thread *td, char *osrelease);
@@ -149,19 +72,12 @@ linux_sysctl_osname(SYSCTL_HANDLER_ARGS)
char osname[LINUX_MAX_UTSNAME];
int error;
- LIN_SDT_PROBE0(mib, linux_sysctl_osname, entry);
-
linux_get_osname(req->td, osname);
error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req);
- if (error != 0 || req->newptr == NULL) {
- LIN_SDT_PROBE1(mib, linux_sysctl_osname, sysctl_string_error,
- error);
- LIN_SDT_PROBE1(mib, linux_sysctl_osname, return, error);
+ if (error != 0 || req->newptr == NULL)
return (error);
- }
error = linux_set_osname(req->td, osname);
- LIN_SDT_PROBE1(mib, linux_sysctl_osname, return, error);
return (error);
}
@@ -176,19 +92,12 @@ linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS)
char osrelease[LINUX_MAX_UTSNAME];
int error;
- LIN_SDT_PROBE0(mib, linux_sysctl_osrelease, entry);
-
linux_get_osrelease(req->td, osrelease);
error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req);
- if (error != 0 || req->newptr == NULL) {
- LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, sysctl_string_error,
- error);
- LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, return, error);
+ if (error != 0 || req->newptr == NULL)
return (error);
- }
error = linux_set_osrelease(req->td, osrelease);
- LIN_SDT_PROBE1(mib, linux_sysctl_osrelease, return, error);
return (error);
}
@@ -203,19 +112,12 @@ linux_sysctl_oss_version(SYSCTL_HANDLER_ARGS)
int oss_version;
int error;
- LIN_SDT_PROBE0(mib, linux_sysctl_oss_version, entry);
-
oss_version = linux_get_oss_version(req->td);
error = sysctl_handle_int(oidp, &oss_version, 0, req);
- if (error != 0 || req->newptr == NULL) {
- LIN_SDT_PROBE1(mib, linux_sysctl_oss_version,
- sysctl_string_error, error);
- LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, return, error);
+ if (error != 0 || req->newptr == NULL)
return (error);
- }
error = linux_set_oss_version(req->td, oss_version);
- LIN_SDT_PROBE1(mib, linux_sysctl_oss_version, return, error);
return (error);
}
@@ -233,37 +135,26 @@ linux_map_osrel(char *osrelease, int *osrel)
char *sep, *eosrelease;
int len, v0, v1, v2, v;
- LIN_SDT_PROBE2(mib, linux_map_osrel, entry, osrelease, osrel);
-
len = strlen(osrelease);
eosrelease = osrelease + len;
v0 = strtol(osrelease, &sep, 10);
- if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') {
- LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
+ if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
return (EINVAL);
- }
osrelease = sep + 1;
v1 = strtol(osrelease, &sep, 10);
- if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') {
- LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
+ if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.')
return (EINVAL);
- }
osrelease = sep + 1;
v2 = strtol(osrelease, &sep, 10);
- if (osrelease == sep || sep != eosrelease) {
- LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
+ if (osrelease == sep || sep != eosrelease)
return (EINVAL);
- }
v = v0 * 1000000 + v1 * 1000 + v2;
- if (v < 1000000) {
- LIN_SDT_PROBE1(mib, linux_map_osrel, return, EINVAL);
+ if (v < 1000000)
return (EINVAL);
- }
*osrel = v;
- LIN_SDT_PROBE1(mib, linux_map_osrel, return, 0);
return (0);
}
@@ -277,8 +168,6 @@ linux_find_prison(struct prison *spr, struct prison **prp)
struct prison *pr;
struct linux_prison *lpr;
- LIN_SDT_PROBE2(mib, linux_get_prison, entry, spr, prp);
-
if (!linux_osd_jail_slot)
/* In case osd_register failed. */
spr = &prison0;
@@ -293,7 +182,6 @@ linux_find_prison(struct prison *spr, struct prison **prp)
}
*prp = pr;
- LIN_SDT_PROBE1(mib, linux_get_prison, return, lpr);
return (lpr);
}
@@ -308,8 +196,6 @@ linux_alloc_prison(struct prison *pr, struct linux_prison **lprp)
struct linux_prison *lpr, *nlpr;
int error;
- LIN_SDT_PROBE2(mib, linux_alloc_prison, entry, pr, lprp);
-
/* If this prison already has Linux info, return that. */
error = 0;
lpr = linux_find_prison(pr, &ppr);
@@ -343,7 +229,6 @@ linux_alloc_prison(struct prison *pr, struct linux_prison **lprp)
else
mtx_unlock(&pr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_alloc_prison, return, error);
return (error);
}
@@ -355,26 +240,16 @@ linux_prison_create(void *obj, void *data)
{
struct prison *pr = obj;
struct vfsoptlist *opts = data;
- int jsys, error;
-
- LIN_SDT_PROBE2(mib, linux_prison_create, entry, obj, data);
+ int jsys;
- error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_create, vfs_copyopt_error,
- error);
- } else if (jsys == JAIL_SYS_INHERIT) {
- LIN_SDT_PROBE1(mib, linux_prison_create, return, 0);
+ if (vfs_copyopt(opts, "linux", &jsys, sizeof(jsys)) == 0 &&
+ jsys == JAIL_SYS_INHERIT)
return (0);
- }
/*
* Inherit a prison's initial values from its parent
* (different from JAIL_SYS_INHERIT which also inherits changes).
*/
- error = linux_alloc_prison(pr, NULL);
-
- LIN_SDT_PROBE1(mib, linux_prison_create, return, error);
- return (error);
+ return (linux_alloc_prison(pr, NULL));
}
static int
@@ -384,80 +259,46 @@ linux_prison_check(void *obj __unused, void *data)
char *osname, *osrelease;
int error, jsys, len, osrel, oss_version;
- LIN_SDT_PROBE2(mib, linux_prison_check, entry, obj, data);
-
/* Check that the parameters are correct. */
error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_check, vfs_copyopt_error,
- error);
- }
if (error != ENOENT) {
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
+ if (error != 0)
return (error);
- }
- if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT) {
- LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
+ if (jsys != JAIL_SYS_NEW && jsys != JAIL_SYS_INHERIT)
return (EINVAL);
- }
}
error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len);
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_check, vfs_getopt_error,
- error);
- }
if (error != ENOENT) {
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
+ if (error != 0)
return (error);
- }
- if (len == 0 || osname[len - 1] != '\0') {
- LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
+ if (len == 0 || osname[len - 1] != '\0')
return (EINVAL);
- }
if (len > LINUX_MAX_UTSNAME) {
vfs_opterror(opts, "linux.osname too long");
- LIN_SDT_PROBE1(mib, linux_prison_check, return,
- ENAMETOOLONG);
return (ENAMETOOLONG);
}
}
error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len);
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_check, vfs_getopt_error,
- error);
- }
if (error != ENOENT) {
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
+ if (error != 0)
return (error);
- }
- if (len == 0 || osrelease[len - 1] != '\0') {
- LIN_SDT_PROBE1(mib, linux_prison_check, return, EINVAL);
+ if (len == 0 || osrelease[len - 1] != '\0')
return (EINVAL);
- }
if (len > LINUX_MAX_UTSNAME) {
vfs_opterror(opts, "linux.osrelease too long");
- LIN_SDT_PROBE1(mib, linux_prison_check, return,
- ENAMETOOLONG);
return (ENAMETOOLONG);
}
error = linux_map_osrel(osrelease, &osrel);
if (error != 0) {
vfs_opterror(opts, "linux.osrelease format error");
- LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
return (error);
}
}
error = vfs_copyopt(opts, "linux.oss_version", &oss_version,
sizeof(oss_version));
- if (error != 0)
- LIN_SDT_PROBE1(mib, linux_prison_check, vfs_copyopt_error, error);
if (error == ENOENT)
error = 0;
- LIN_SDT_PROBE1(mib, linux_prison_check, return, error);
return (error);
}
@@ -470,32 +311,22 @@ linux_prison_set(void *obj, void *data)
char *osname, *osrelease;
int error, gotversion, jsys, len, oss_version;
- LIN_SDT_PROBE2(mib, linux_prison_set, entry, obj, data);
-
/* Set the parameters, which should be correct. */
error = vfs_copyopt(opts, "linux", &jsys, sizeof(jsys));
- if (error != 0)
- LIN_SDT_PROBE1(mib, linux_prison_set, vfs_copyopt_error, error);
if (error == ENOENT)
jsys = -1;
error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len);
- if (error != 0)
- LIN_SDT_PROBE1(mib, linux_prison_set, vfs_getopt_error, error);
if (error == ENOENT)
osname = NULL;
else
jsys = JAIL_SYS_NEW;
error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len);
- if (error != 0)
- LIN_SDT_PROBE1(mib, linux_prison_set, vfs_getopt_error, error);
if (error == ENOENT)
osrelease = NULL;
else
jsys = JAIL_SYS_NEW;
error = vfs_copyopt(opts, "linux.oss_version", &oss_version,
sizeof(oss_version));
- if (error != 0)
- LIN_SDT_PROBE1(mib, linux_prison_set, vfs_copyopt_error, error);
if (error == ENOENT)
gotversion = 0;
else {
@@ -517,15 +348,12 @@ linux_prison_set(void *obj, void *data)
error = linux_alloc_prison(pr, &lpr);
if (error) {
mtx_unlock(&pr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_prison_set, return, error);
return (error);
}
if (osrelease) {
error = linux_map_osrel(osrelease, &lpr->pr_osrel);
if (error) {
mtx_unlock(&pr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_prison_set, return,
- error);
return (error);
}
strlcpy(lpr->pr_osrelease, osrelease,
@@ -538,7 +366,6 @@ linux_prison_set(void *obj, void *data)
mtx_unlock(&pr->pr_mtx);
}
- LIN_SDT_PROBE1(mib, linux_prison_set, return, 0);
return (0);
}
@@ -561,74 +388,44 @@ linux_prison_get(void *obj, void *data)
static int version0;
- LIN_SDT_PROBE2(mib, linux_prison_get, entry, obj, data);
-
/* See if this prison is the one with the Linux info. */
lpr = linux_find_prison(pr, &ppr);
i = (ppr == pr) ? JAIL_SYS_NEW : JAIL_SYS_INHERIT;
error = vfs_setopt(opts, "linux", &i, sizeof(i));
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error, error);
- if (error != ENOENT)
- goto done;
- }
+ if (error != 0 && error != ENOENT)
+ goto done;
if (i) {
error = vfs_setopts(opts, "linux.osname", lpr->pr_osname);
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
- error);
- if (error != ENOENT)
- goto done;
- }
+ if (error != 0 && error != ENOENT)
+ goto done;
error = vfs_setopts(opts, "linux.osrelease", lpr->pr_osrelease);
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
- error);
- if (error != ENOENT)
- goto done;
- }
+ if (error != 0 && error != ENOENT)
+ goto done;
error = vfs_setopt(opts, "linux.oss_version",
&lpr->pr_oss_version, sizeof(lpr->pr_oss_version));
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error,
- error);
- if(error != ENOENT)
- goto done;
- }
+ if (error != 0 && error != ENOENT)
+ goto done;
} else {
/*
* If this prison is inheriting its Linux info, report
* empty/zero parameters.
*/
error = vfs_setopts(opts, "linux.osname", "");
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
- error);
- if(error != ENOENT)
- goto done;
- }
+ if (error != 0 && error != ENOENT)
+ goto done;
error = vfs_setopts(opts, "linux.osrelease", "");
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopts_error,
- error);
- if(error != ENOENT)
- goto done;
- }
+ if (error != 0 && error != ENOENT)
+ goto done;
error = vfs_setopt(opts, "linux.oss_version", &version0,
sizeof(lpr->pr_oss_version));
- if (error != 0) {
- LIN_SDT_PROBE1(mib, linux_prison_get, vfs_setopt_error,
- error);
- if(error != ENOENT)
- goto done;
- }
+ if (error != 0 && error != ENOENT)
+ goto done;
}
error = 0;
done:
mtx_unlock(&ppr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_prison_get, return, error);
return (error);
}
@@ -636,9 +433,7 @@ static void
linux_prison_destructor(void *data)
{
- LIN_SDT_PROBE1(mib, linux_prison_destructor, entry, data);
free(data, M_PRISON);
- LIN_SDT_PROBE0(mib, linux_prison_destructor, return);
}
void
@@ -652,8 +447,6 @@ linux_osd_jail_register(void)
[PR_METHOD_CHECK] = linux_prison_check
};
- LIN_SDT_PROBE0(mib, linux_osd_jail_register, entry);
-
linux_osd_jail_slot =
osd_jail_register(linux_prison_destructor, methods);
if (linux_osd_jail_slot > 0) {
@@ -663,20 +456,14 @@ linux_osd_jail_register(void)
(void)linux_alloc_prison(pr, NULL);
sx_xunlock(&allprison_lock);
}
-
- LIN_SDT_PROBE0(mib, linux_osd_jail_register, return);
}
void
linux_osd_jail_deregister(void)
{
- LIN_SDT_PROBE0(mib, linux_osd_jail_register, entry);
-
if (linux_osd_jail_slot)
osd_jail_deregister(linux_osd_jail_slot);
-
- LIN_SDT_PROBE0(mib, linux_osd_jail_register, return);
}
void
@@ -685,13 +472,9 @@ linux_get_osname(struct thread *td, char *dst)
struct prison *pr;
struct linux_prison *lpr;
- LIN_SDT_PROBE2(mib, linux_get_osname, entry, td, dst);
-
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
-
- LIN_SDT_PROBE0(mib, linux_get_osname, return);
}
static int
@@ -700,13 +483,10 @@ linux_set_osname(struct thread *td, char *osname)
struct prison *pr;
struct linux_prison *lpr;
- LIN_SDT_PROBE2(mib, linux_set_osname, entry, td, osname);
-
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_set_osname, return, 0);
return (0);
}
@@ -716,13 +496,9 @@ linux_get_osrelease(struct thread *td, char *dst)
struct prison *pr;
struct linux_prison *lpr;
- LIN_SDT_PROBE2(mib, linux_get_osrelease, entry, td, dst);
-
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
bcopy(lpr->pr_osrelease, dst, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
-
- LIN_SDT_PROBE0(mib, linux_get_osrelease, return);
}
int
@@ -732,13 +508,10 @@ linux_kernver(struct thread *td)
struct linux_prison *lpr;
int osrel;
- LIN_SDT_PROBE1(mib, linux_kernver, entry, td);
-
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
osrel = lpr->pr_osrel;
mtx_unlock(&pr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_kernver, return, osrel);
return (osrel);
}
@@ -749,15 +522,12 @@ linux_set_osrelease(struct thread *td, char *osrelease)
struct linux_prison *lpr;
int error;
- LIN_SDT_PROBE2(mib, linux_set_osrelease, entry, td, osrelease);
-
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
error = linux_map_osrel(osrelease, &lpr->pr_osrel);
if (error == 0)
strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME);
mtx_unlock(&pr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_set_osrelease, return, error);
return (error);
}
@@ -768,13 +538,10 @@ linux_get_oss_version(struct thread *td)
struct linux_prison *lpr;
int version;
- LIN_SDT_PROBE1(mib, linux_get_oss_version, entry, td);
-
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
version = lpr->pr_oss_version;
mtx_unlock(&pr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_get_oss_version, return, version);
return (version);
}
@@ -784,74 +551,9 @@ linux_set_oss_version(struct thread *td, int oss_version)
struct prison *pr;
struct linux_prison *lpr;
- LIN_SDT_PROBE2(mib, linux_set_oss_version, entry, td, oss_version);
-
lpr = linux_find_prison(td->td_ucred->cr_prison, &pr);
lpr->pr_oss_version = oss_version;
mtx_unlock(&pr->pr_mtx);
- LIN_SDT_PROBE1(mib, linux_set_oss_version, return, 0);
return (0);
}
-
-#if defined(DEBUG) || defined(KTR)
-/* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */
-
-u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))];
-
-static int
-linux_debug(int syscall, int toggle, int global)
-{
-
- if (global) {
- char c = toggle ? 0 : 0xff;
-
- memset(linux_debug_map, c, sizeof(linux_debug_map));
- return (0);
- }
- if (syscall < 0 || syscall >= LINUX_SYS_MAXSYSCALL)
- return (EINVAL);
- if (toggle)
- clrbit(linux_debug_map, syscall);
- else
- setbit(linux_debug_map, syscall);
- return (0);
-}
-
-/*
- * Usage: sysctl linux.debug=<syscall_nr>.<0/1>
- *
- * E.g.: sysctl linux.debug=21.0
- *
- * As a special case, syscall "all" will apply to all syscalls globally.
- */
-#define LINUX_MAX_DEBUGSTR 16
-static int
-linux_sysctl_debug(SYSCTL_HANDLER_ARGS)
-{
- char value[LINUX_MAX_DEBUGSTR], *p;
- int error, sysc, toggle;
- int global = 0;
-
- value[0] = '\0';
- error = sysctl_handle_string(oidp, value, LINUX_MAX_DEBUGSTR, req);
- if (error || req->newptr == NULL)
- return (error);
- for (p = value; *p != '\0' && *p != '.'; p++);
- if (*p == '\0')
- return (EINVAL);
- *p++ = '\0';
- sysc = strtol(value, NULL, 0);
- toggle = strtol(p, NULL, 0);
- if (strcmp(value, "all") == 0)
- global = 1;
- error = linux_debug(sysc, toggle, global);
- return (error);
-}
-
-SYSCTL_PROC(_compat_linux, OID_AUTO, debug,
- CTLTYPE_STRING | CTLFLAG_RW,
- 0, 0, linux_sysctl_debug, "A",
- "Linux debugging control");
-
-#endif /* DEBUG || KTR */
diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h
index e8eedf906443..80b6c973e3e9 100644
--- a/sys/compat/linux/linux_mib.h
+++ b/sys/compat/linux/linux_mib.h
@@ -31,6 +31,10 @@
#ifndef _LINUX_MIB_H_
#define _LINUX_MIB_H_
+#ifdef SYSCTL_DECL
+SYSCTL_DECL(_compat_linux);
+#endif
+
void linux_osd_jail_register(void);
void linux_osd_jail_deregister(void);
@@ -42,8 +46,19 @@ int linux_get_oss_version(struct thread *td);
int linux_kernver(struct thread *td);
-#define LINUX_KERNVER_2004000 2004000
-#define LINUX_KERNVER_2006000 2006000
+#define LINUX_KVERSION 2
+#define LINUX_KPATCHLEVEL 6
+#define LINUX_KSUBLEVEL 32
+
+#define LINUX_KERNVER(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#define LINUX_VERSION_CODE LINUX_KERNVER(LINUX_KVERSION, \
+ LINUX_KPATCHLEVEL, LINUX_KSUBLEVEL)
+#define LINUX_KERNVERSTR(x) #x
+#define LINUX_XKERNVERSTR(x) LINUX_KERNVERSTR(x)
+#define LINUX_VERSION_STR LINUX_XKERNVERSTR(LINUX_KVERSION.LINUX_KPATCHLEVEL.LINUX_KSUBLEVEL)
+
+#define LINUX_KERNVER_2004000 LINUX_KERNVER(2,4,0)
+#define LINUX_KERNVER_2006000 LINUX_KERNVER(2,6,0)
#define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000)
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index ec531d39df1c..fa5feaf01daf 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -88,21 +88,24 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_file.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_timer.h>
#include <compat/linux/linux_util.h>
#include <compat/linux/linux_sysproto.h>
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_misc.h>
-/* DTrace init */
-LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
-
-/* Linuxulator-global DTrace probes */
-LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked);
-LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock);
-LIN_SDT_PROBE_DECLARE(locks, emul_shared_rlock, locked);
-LIN_SDT_PROBE_DECLARE(locks, emul_shared_rlock, unlock);
-LIN_SDT_PROBE_DECLARE(locks, emul_shared_wlock, locked);
-LIN_SDT_PROBE_DECLARE(locks, emul_shared_wlock, unlock);
+/**
+ * Special DTrace provider for the linuxulator.
+ *
+ * In this file we define the provider for the entire linuxulator. All
+ * modules (= files of the linuxulator) use it.
+ *
+ * We define a different name depending on the emulated bitsize, see
+ * ../../<ARCH>/linux{,32}/linux.h, e.g.:
+ * native bitsize = linuxulator
+ * amd64, 32bit emulation = linuxulator32
+ */
+LIN_SDT_PROVIDER_DEFINE(LINUX_DTRACE);
int stclohz; /* Statistics clock frequency */
@@ -129,6 +132,15 @@ struct l_sysinfo {
l_uint mem_unit;
char _f[20-2*sizeof(l_long)-sizeof(l_int)]; /* padding */
};
+
+struct l_pselect6arg {
+ l_uintptr_t ss;
+ l_size_t ss_len;
+};
+
+static int linux_utimensat_nsec_valid(l_long);
+
+
int
linux_sysinfo(struct thread *td, struct linux_sysinfo_args *args)
{
@@ -371,7 +383,7 @@ linux_uselib(struct thread *td, struct linux_uselib_args *args)
*/
PROC_LOCK(td->td_proc);
if (a_out->a_text > maxtsiz ||
- a_out->a_data + bss_size > lim_cur(td->td_proc, RLIMIT_DATA) ||
+ a_out->a_data + bss_size > lim_cur_proc(td->td_proc, RLIMIT_DATA) ||
racct_set(td->td_proc, RACCT_DATA, a_out->a_data +
bss_size) != 0) {
PROC_UNLOCK(td->td_proc);
@@ -523,7 +535,7 @@ linux_select(struct thread *td, struct linux_select_args *args)
tvp = NULL;
error = kern_select(td, args->nfds, args->readfds, args->writefds,
- args->exceptfds, tvp, sizeof(l_int) * 8);
+ args->exceptfds, tvp, LINUX_NFDBITS);
#ifdef DEBUG
if (ldebug(select))
@@ -738,12 +750,11 @@ linux_newuname(struct thread *td, struct linux_newuname_args *args)
*p = '\0';
break;
}
- strlcpy(utsname.machine, linux_platform, LINUX_MAX_UTSNAME);
+ strlcpy(utsname.machine, linux_kplatform, LINUX_MAX_UTSNAME);
return (copyout(&utsname, args->buf, sizeof(utsname)));
}
-#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
struct l_utimbuf {
l_time_t l_actime;
l_time_t l_modtime;
@@ -816,6 +827,98 @@ linux_utimes(struct thread *td, struct linux_utimes_args *args)
return (error);
}
+static int
+linux_utimensat_nsec_valid(l_long nsec)
+{
+
+ if (nsec == LINUX_UTIME_OMIT || nsec == LINUX_UTIME_NOW)
+ return (0);
+ if (nsec >= 0 && nsec <= 999999999)
+ return (0);
+ return (1);
+}
+
+int
+linux_utimensat(struct thread *td, struct linux_utimensat_args *args)
+{
+ struct l_timespec l_times[2];
+ struct timespec times[2], *timesp = NULL;
+ char *path = NULL;
+ int error, dfd, flags = 0;
+
+ dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
+
+#ifdef DEBUG
+ if (ldebug(utimensat))
+ printf(ARGS(utimensat, "%d, *"), dfd);
+#endif
+
+ if (args->flags & ~LINUX_AT_SYMLINK_NOFOLLOW)
+ return (EINVAL);
+
+ if (args->times != NULL) {
+ error = copyin(args->times, l_times, sizeof(l_times));
+ if (error != 0)
+ return (error);
+
+ if (linux_utimensat_nsec_valid(l_times[0].tv_nsec) != 0 ||
+ linux_utimensat_nsec_valid(l_times[1].tv_nsec) != 0)
+ return (EINVAL);
+
+ times[0].tv_sec = l_times[0].tv_sec;
+ switch (l_times[0].tv_nsec)
+ {
+ case LINUX_UTIME_OMIT:
+ times[0].tv_nsec = UTIME_OMIT;
+ break;
+ case LINUX_UTIME_NOW:
+ times[0].tv_nsec = UTIME_NOW;
+ break;
+ default:
+ times[0].tv_nsec = l_times[0].tv_nsec;
+ }
+
+ times[1].tv_sec = l_times[1].tv_sec;
+ switch (l_times[1].tv_nsec)
+ {
+ case LINUX_UTIME_OMIT:
+ times[1].tv_nsec = UTIME_OMIT;
+ break;
+ case LINUX_UTIME_NOW:
+ times[1].tv_nsec = UTIME_NOW;
+ break;
+ default:
+ times[1].tv_nsec = l_times[1].tv_nsec;
+ break;
+ }
+ timesp = times;
+ }
+
+ if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT)
+ /* This breaks POSIX, but is what the Linux kernel does
+ * _on purpose_ (documented in the man page for utimensat(2)),
+ * so we must follow that behaviour. */
+ return (0);
+
+ if (args->pathname != NULL)
+ LCONVPATHEXIST_AT(td, args->pathname, &path, dfd);
+ else if (args->flags != 0)
+ return (EINVAL);
+
+ if (args->flags & LINUX_AT_SYMLINK_NOFOLLOW)
+ flags |= AT_SYMLINK_NOFOLLOW;
+
+ if (path == NULL)
+ error = kern_futimens(td, dfd, timesp, UIO_SYSSPACE);
+ else {
+ error = kern_utimensat(td, dfd, path, UIO_SYSSPACE, timesp,
+ UIO_SYSSPACE, flags);
+ LFREEPATH(path);
+ }
+
+ return (error);
+}
+
int
linux_futimesat(struct thread *td, struct linux_futimesat_args *args)
{
@@ -848,7 +951,6 @@ linux_futimesat(struct thread *td, struct linux_futimesat_args *args)
LFREEPATH(fname);
return (error);
}
-#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
linux_common_wait(struct thread *td, int pid, int *status,
@@ -864,41 +966,131 @@ linux_common_wait(struct thread *td, int pid, int *status,
tmpstat &= 0xffff;
if (WIFSIGNALED(tmpstat))
tmpstat = (tmpstat & 0xffffff80) |
- BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat));
+ bsd_to_linux_signal(WTERMSIG(tmpstat));
else if (WIFSTOPPED(tmpstat))
tmpstat = (tmpstat & 0xffff00ff) |
- (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8);
+ (bsd_to_linux_signal(WSTOPSIG(tmpstat)) << 8);
+ else if (WIFCONTINUED(tmpstat))
+ tmpstat = 0xffff;
error = copyout(&tmpstat, status, sizeof(int));
}
return (error);
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_waitpid(struct thread *td, struct linux_waitpid_args *args)
{
- int options;
-
+ struct linux_wait4_args wait4_args;
+
#ifdef DEBUG
if (ldebug(waitpid))
printf(ARGS(waitpid, "%d, %p, %d"),
args->pid, (void *)args->status, args->options);
#endif
- /*
- * this is necessary because the test in kern_wait doesn't work
- * because we mess with the options here
- */
- if (args->options & ~(WUNTRACED | WNOHANG | WCONTINUED | __WCLONE))
+
+ wait4_args.pid = args->pid;
+ wait4_args.status = args->status;
+ wait4_args.options = args->options;
+ wait4_args.rusage = NULL;
+
+ return (linux_wait4(td, &wait4_args));
+}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
+int
+linux_wait4(struct thread *td, struct linux_wait4_args *args)
+{
+ int error, options;
+ struct rusage ru, *rup;
+
+#ifdef DEBUG
+ if (ldebug(wait4))
+ printf(ARGS(wait4, "%d, %p, %d, %p"),
+ args->pid, (void *)args->status, args->options,
+ (void *)args->rusage);
+#endif
+ if (args->options & ~(LINUX_WUNTRACED | LINUX_WNOHANG |
+ LINUX_WCONTINUED | __WCLONE | __WNOTHREAD | __WALL))
return (EINVAL);
-
- options = (args->options & (WNOHANG | WUNTRACED));
- /* WLINUXCLONE should be equal to __WCLONE, but we make sure */
- if (args->options & __WCLONE)
- options |= WLINUXCLONE;
- return (linux_common_wait(td, args->pid, args->status, options, NULL));
+ options = WEXITED;
+ linux_to_bsd_waitopts(args->options, &options);
+
+ if (args->rusage != NULL)
+ rup = &ru;
+ else
+ rup = NULL;
+ error = linux_common_wait(td, args->pid, args->status, options, rup);
+ if (error != 0)
+ return (error);
+ if (args->rusage != NULL)
+ error = linux_copyout_rusage(&ru, args->rusage);
+ return (error);
}
+int
+linux_waitid(struct thread *td, struct linux_waitid_args *args)
+{
+ int status, options, sig;
+ struct __wrusage wru;
+ siginfo_t siginfo;
+ l_siginfo_t lsi;
+ idtype_t idtype;
+ struct proc *p;
+ int error;
+
+ options = 0;
+ linux_to_bsd_waitopts(args->options, &options);
+
+ if (options & ~(WNOHANG | WNOWAIT | WEXITED | WUNTRACED | WCONTINUED))
+ return (EINVAL);
+ if (!(options & (WEXITED | WUNTRACED | WCONTINUED)))
+ return (EINVAL);
+
+ switch (args->idtype) {
+ case LINUX_P_ALL:
+ idtype = P_ALL;
+ break;
+ case LINUX_P_PID:
+ if (args->id <= 0)
+ return (EINVAL);
+ idtype = P_PID;
+ break;
+ case LINUX_P_PGID:
+ if (args->id <= 0)
+ return (EINVAL);
+ idtype = P_PGID;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ error = kern_wait6(td, idtype, args->id, &status, options,
+ &wru, &siginfo);
+ if (error != 0)
+ return (error);
+ if (args->rusage != NULL) {
+ error = linux_copyout_rusage(&wru.wru_children,
+ args->rusage);
+ if (error != 0)
+ return (error);
+ }
+ if (args->info != NULL) {
+ p = td->td_proc;
+ if (td->td_retval[0] == 0)
+ bzero(&lsi, sizeof(lsi));
+ else {
+ sig = bsd_to_linux_signal(siginfo.si_signo);
+ siginfo_to_lsiginfo(&siginfo, &lsi, sig);
+ }
+ error = copyout(&lsi, args->info, sizeof(lsi));
+ }
+ td->td_retval[0] = 0;
+
+ return (error);
+}
int
linux_mknod(struct thread *td, struct linux_mknod_args *args)
@@ -910,7 +1102,8 @@ linux_mknod(struct thread *td, struct linux_mknod_args *args)
#ifdef DEBUG
if (ldebug(mknod))
- printf(ARGS(mknod, "%s, %d, %d"), path, args->mode, args->dev);
+ printf(ARGS(mknod, "%s, %d, %ju"), path, args->mode,
+ (uintmax_t)args->dev);
#endif
switch (args->mode & S_IFMT) {
@@ -1081,6 +1274,7 @@ linux_getitimer(struct thread *td, struct linux_getitimer_args *uap)
return (copyout(&ls, uap->itv, sizeof(ls)));
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_nice(struct thread *td, struct linux_nice_args *args)
{
@@ -1091,6 +1285,7 @@ linux_nice(struct thread *td, struct linux_nice_args *args)
bsd_args.prio = args->inc;
return (sys_setpriority(td, &bsd_args));
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
@@ -1104,7 +1299,7 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
ngrp = args->gidsetsize;
if (ngrp < 0 || ngrp >= ngroups_max + 1)
return (EINVAL);
- linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
+ linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK);
error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t));
if (error)
goto out;
@@ -1143,7 +1338,7 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
crfree(oldcred);
error = 0;
out:
- free(linux_gidset, M_TEMP);
+ free(linux_gidset, M_LINUX);
return (error);
}
@@ -1175,14 +1370,14 @@ linux_getgroups(struct thread *td, struct linux_getgroups_args *args)
ngrp = 0;
linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
- M_TEMP, M_WAITOK);
+ M_LINUX, M_WAITOK);
while (ngrp < bsd_gidsetsz) {
linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
ngrp++;
}
error = copyout(linux_gidset, args->grouplist, ngrp * sizeof(l_gid_t));
- free(linux_gidset, M_TEMP);
+ free(linux_gidset, M_LINUX);
if (error)
return (error);
@@ -1220,11 +1415,11 @@ linux_setrlimit(struct thread *td, struct linux_setrlimit_args *args)
return (kern_setrlimit(td, which, &bsd_rlim));
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args)
{
struct l_rlimit rlim;
- struct proc *p = td->td_proc;
struct rlimit bsd_rlim;
u_int which;
@@ -1241,9 +1436,7 @@ linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args)
if (which == -1)
return (EINVAL);
- PROC_LOCK(p);
- lim_rlimit(p, which, &bsd_rlim);
- PROC_UNLOCK(p);
+ lim_rlimit(td, which, &bsd_rlim);
#ifdef COMPAT_LINUX32
rlim.rlim_cur = (unsigned int)bsd_rlim.rlim_cur;
@@ -1262,12 +1455,12 @@ linux_old_getrlimit(struct thread *td, struct linux_old_getrlimit_args *args)
#endif
return (copyout(&rlim, args->rlim, sizeof(rlim)));
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
linux_getrlimit(struct thread *td, struct linux_getrlimit_args *args)
{
struct l_rlimit rlim;
- struct proc *p = td->td_proc;
struct rlimit bsd_rlim;
u_int which;
@@ -1284,9 +1477,7 @@ linux_getrlimit(struct thread *td, struct linux_getrlimit_args *args)
if (which == -1)
return (EINVAL);
- PROC_LOCK(p);
- lim_rlimit(p, which, &bsd_rlim);
- PROC_UNLOCK(p);
+ lim_rlimit(td, which, &bsd_rlim);
rlim.rlim_cur = (l_ulong)bsd_rlim.rlim_cur;
rlim.rlim_max = (l_ulong)bsd_rlim.rlim_max;
@@ -1297,7 +1488,9 @@ int
linux_sched_setscheduler(struct thread *td,
struct linux_sched_setscheduler_args *args)
{
- struct sched_setscheduler_args bsd;
+ struct sched_param sched_param;
+ struct thread *tdt;
+ int error, policy;
#ifdef DEBUG
if (ldebug(sched_setscheduler))
@@ -1307,39 +1500,51 @@ linux_sched_setscheduler(struct thread *td,
switch (args->policy) {
case LINUX_SCHED_OTHER:
- bsd.policy = SCHED_OTHER;
+ policy = SCHED_OTHER;
break;
case LINUX_SCHED_FIFO:
- bsd.policy = SCHED_FIFO;
+ policy = SCHED_FIFO;
break;
case LINUX_SCHED_RR:
- bsd.policy = SCHED_RR;
+ policy = SCHED_RR;
break;
default:
return (EINVAL);
}
- bsd.pid = args->pid;
- bsd.param = (struct sched_param *)args->param;
- return (sys_sched_setscheduler(td, &bsd));
+ error = copyin(args->param, &sched_param, sizeof(sched_param));
+ if (error)
+ return (error);
+
+ tdt = linux_tdfind(td, args->pid, -1);
+ if (tdt == NULL)
+ return (ESRCH);
+
+ error = kern_sched_setscheduler(td, tdt, policy, &sched_param);
+ PROC_UNLOCK(tdt->td_proc);
+ return (error);
}
int
linux_sched_getscheduler(struct thread *td,
struct linux_sched_getscheduler_args *args)
{
- struct sched_getscheduler_args bsd;
- int error;
+ struct thread *tdt;
+ int error, policy;
#ifdef DEBUG
if (ldebug(sched_getscheduler))
printf(ARGS(sched_getscheduler, "%d"), args->pid);
#endif
- bsd.pid = args->pid;
- error = sys_sched_getscheduler(td, &bsd);
+ tdt = linux_tdfind(td, args->pid, -1);
+ if (tdt == NULL)
+ return (ESRCH);
- switch (td->td_retval[0]) {
+ error = kern_sched_getscheduler(td, tdt, &policy);
+ PROC_UNLOCK(tdt->td_proc);
+
+ switch (policy) {
case SCHED_OTHER:
td->td_retval[0] = LINUX_SCHED_OTHER;
break;
@@ -1350,7 +1555,6 @@ linux_sched_getscheduler(struct thread *td,
td->td_retval[0] = LINUX_SCHED_RR;
break;
}
-
return (error);
}
@@ -1476,20 +1680,12 @@ linux_reboot(struct thread *td, struct linux_reboot_args *args)
int
linux_getpid(struct thread *td, struct linux_getpid_args *args)
{
- struct linux_emuldata *em;
#ifdef DEBUG
if (ldebug(getpid))
printf(ARGS(getpid, ""));
#endif
-
- if (linux_use26(td)) {
- em = em_find(td->td_proc, EMUL_DONTLOCK);
- KASSERT(em != NULL, ("getpid: emuldata not found.\n"));
- td->td_retval[0] = em->shared->group_pid;
- } else {
- td->td_retval[0] = td->td_proc->p_pid;
- }
+ td->td_retval[0] = td->td_proc->p_pid;
return (0);
}
@@ -1497,13 +1693,18 @@ linux_getpid(struct thread *td, struct linux_getpid_args *args)
int
linux_gettid(struct thread *td, struct linux_gettid_args *args)
{
+ struct linux_emuldata *em;
#ifdef DEBUG
if (ldebug(gettid))
printf(ARGS(gettid, ""));
#endif
- td->td_retval[0] = td->td_proc->p_pid;
+ em = em_find(td);
+ KASSERT(em != NULL, ("gettid: emuldata not found.\n"));
+
+ td->td_retval[0] = em->em_tid;
+
return (0);
}
@@ -1511,50 +1712,15 @@ linux_gettid(struct thread *td, struct linux_gettid_args *args)
int
linux_getppid(struct thread *td, struct linux_getppid_args *args)
{
- struct linux_emuldata *em;
- struct proc *p, *pp;
#ifdef DEBUG
if (ldebug(getppid))
printf(ARGS(getppid, ""));
#endif
- if (!linux_use26(td)) {
- PROC_LOCK(td->td_proc);
- td->td_retval[0] = td->td_proc->p_pptr->p_pid;
- PROC_UNLOCK(td->td_proc);
- return (0);
- }
-
- em = em_find(td->td_proc, EMUL_DONTLOCK);
-
- KASSERT(em != NULL, ("getppid: process emuldata not found.\n"));
-
- /* find the group leader */
- p = pfind(em->shared->group_pid);
-
- if (p == NULL) {
-#ifdef DEBUG
- printf(LMSG("parent process not found.\n"));
-#endif
- return (0);
- }
-
- pp = p->p_pptr; /* switch to parent */
- PROC_LOCK(pp);
- PROC_UNLOCK(p);
-
- /* if its also linux process */
- if (pp->p_sysent == &elf_linux_sysvec) {
- em = em_find(pp, EMUL_DONTLOCK);
- KASSERT(em != NULL, ("getppid: parent emuldata not found.\n"));
-
- td->td_retval[0] = em->shared->group_pid;
- } else
- td->td_retval[0] = pp->p_pid;
-
- PROC_UNLOCK(pp);
-
+ PROC_LOCK(td->td_proc);
+ td->td_retval[0] = td->td_proc->p_pptr->p_pid;
+ PROC_UNLOCK(td->td_proc);
return (0);
}
@@ -1659,22 +1825,14 @@ linux_setdomainname(struct thread *td, struct linux_setdomainname_args *args)
int
linux_exit_group(struct thread *td, struct linux_exit_group_args *args)
{
- struct linux_emuldata *em;
#ifdef DEBUG
if (ldebug(exit_group))
printf(ARGS(exit_group, "%i"), args->error_code);
#endif
- em = em_find(td->td_proc, EMUL_DONTLOCK);
- if (em->shared->refs > 1) {
- EMUL_SHARED_WLOCK(&emul_shared_lock);
- em->shared->flags |= EMUL_SHARED_HASXSTAT;
- em->shared->xstat = W_EXITCODE(args->error_code, 0);
- EMUL_SHARED_WUNLOCK(&emul_shared_lock);
- if (linux_use26(td))
- linux_kill_threads(td, SIGKILL);
- }
+ LINUX_CTR2(exit_group, "thread(%d) (%d)", td->td_tid,
+ args->error_code);
/*
* XXX: we should send a signal to the parent if
@@ -1682,8 +1840,7 @@ linux_exit_group(struct thread *td, struct linux_exit_group_args *args)
* as it doesnt occur often.
*/
exit1(td, W_EXITCODE(args->error_code, 0));
-
- return (0);
+ /* NOTREACHED */
}
#define _LINUX_CAPABILITY_VERSION 0x19980330
@@ -1791,24 +1948,23 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args)
#ifdef DEBUG
if (ldebug(prctl))
- printf(ARGS(prctl, "%d, %d, %d, %d, %d"), args->option,
- args->arg2, args->arg3, args->arg4, args->arg5);
+ printf(ARGS(prctl, "%d, %ju, %ju, %ju, %ju"), args->option,
+ (uintmax_t)args->arg2, (uintmax_t)args->arg3,
+ (uintmax_t)args->arg4, (uintmax_t)args->arg5);
#endif
switch (args->option) {
case LINUX_PR_SET_PDEATHSIG:
if (!LINUX_SIG_VALID(args->arg2))
return (EINVAL);
- em = em_find(p, EMUL_DOLOCK);
+ em = em_find(td);
KASSERT(em != NULL, ("prctl: emuldata not found.\n"));
em->pdeath_signal = args->arg2;
- EMUL_UNLOCK(&emul_lock);
break;
case LINUX_PR_GET_PDEATHSIG:
- em = em_find(p, EMUL_DOLOCK);
+ em = em_find(td);
KASSERT(em != NULL, ("prctl: emuldata not found.\n"));
pdeath_signal = em->pdeath_signal;
- EMUL_UNLOCK(&emul_lock);
error = copyout(&pdeath_signal,
(void *)(register_t)args->arg2,
sizeof(pdeath_signal));
@@ -1873,6 +2029,57 @@ linux_prctl(struct thread *td, struct linux_prctl_args *args)
return (error);
}
+int
+linux_sched_setparam(struct thread *td,
+ struct linux_sched_setparam_args *uap)
+{
+ struct sched_param sched_param;
+ struct thread *tdt;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(sched_setparam))
+ printf(ARGS(sched_setparam, "%d, *"), uap->pid);
+#endif
+
+ error = copyin(uap->param, &sched_param, sizeof(sched_param));
+ if (error)
+ return (error);
+
+ tdt = linux_tdfind(td, uap->pid, -1);
+ if (tdt == NULL)
+ return (ESRCH);
+
+ error = kern_sched_setparam(td, tdt, &sched_param);
+ PROC_UNLOCK(tdt->td_proc);
+ return (error);
+}
+
+int
+linux_sched_getparam(struct thread *td,
+ struct linux_sched_getparam_args *uap)
+{
+ struct sched_param sched_param;
+ struct thread *tdt;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(sched_getparam))
+ printf(ARGS(sched_getparam, "%d, *"), uap->pid);
+#endif
+
+ tdt = linux_tdfind(td, uap->pid, -1);
+ if (tdt == NULL)
+ return (ESRCH);
+
+ error = kern_sched_getparam(td, tdt, &sched_param);
+ PROC_UNLOCK(tdt->td_proc);
+ if (error == 0)
+ error = copyout(&sched_param, uap->param,
+ sizeof(sched_param));
+ return (error);
+}
+
/*
* Get affinity of a process.
*/
@@ -1881,6 +2088,7 @@ linux_sched_getaffinity(struct thread *td,
struct linux_sched_getaffinity_args *args)
{
int error;
+ struct thread *tdt;
struct cpuset_getaffinity_args cga;
#ifdef DEBUG
@@ -1891,9 +2099,14 @@ linux_sched_getaffinity(struct thread *td,
if (args->len < sizeof(cpuset_t))
return (EINVAL);
+ tdt = linux_tdfind(td, args->pid, -1);
+ if (tdt == NULL)
+ return (ESRCH);
+
+ PROC_UNLOCK(tdt->td_proc);
cga.level = CPU_LEVEL_WHICH;
- cga.which = CPU_WHICH_PID;
- cga.id = args->pid;
+ cga.which = CPU_WHICH_TID;
+ cga.id = tdt->td_tid;
cga.cpusetsize = sizeof(cpuset_t);
cga.mask = (cpuset_t *) args->user_mask_ptr;
@@ -1911,6 +2124,7 @@ linux_sched_setaffinity(struct thread *td,
struct linux_sched_setaffinity_args *args)
{
struct cpuset_setaffinity_args csa;
+ struct thread *tdt;
#ifdef DEBUG
if (ldebug(sched_setaffinity))
@@ -1920,11 +2134,369 @@ linux_sched_setaffinity(struct thread *td,
if (args->len < sizeof(cpuset_t))
return (EINVAL);
+ tdt = linux_tdfind(td, args->pid, -1);
+ if (tdt == NULL)
+ return (ESRCH);
+
+ PROC_UNLOCK(tdt->td_proc);
csa.level = CPU_LEVEL_WHICH;
- csa.which = CPU_WHICH_PID;
- csa.id = args->pid;
+ csa.which = CPU_WHICH_TID;
+ csa.id = tdt->td_tid;
csa.cpusetsize = sizeof(cpuset_t);
csa.mask = (cpuset_t *) args->user_mask_ptr;
return (sys_cpuset_setaffinity(td, &csa));
}
+
+struct linux_rlimit64 {
+ uint64_t rlim_cur;
+ uint64_t rlim_max;
+};
+
+int
+linux_prlimit64(struct thread *td, struct linux_prlimit64_args *args)
+{
+ struct rlimit rlim, nrlim;
+ struct linux_rlimit64 lrlim;
+ struct proc *p;
+ u_int which;
+ int flags;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(prlimit64))
+ printf(ARGS(prlimit64, "%d, %d, %p, %p"), args->pid,
+ args->resource, (void *)args->new, (void *)args->old);
+#endif
+
+ if (args->resource >= LINUX_RLIM_NLIMITS)
+ return (EINVAL);
+
+ which = linux_to_bsd_resource[args->resource];
+ if (which == -1)
+ return (EINVAL);
+
+ if (args->new != NULL) {
+ /*
+ * Note. Unlike FreeBSD where rlim is signed 64-bit Linux
+ * rlim is unsigned 64-bit. FreeBSD treats negative limits
+ * as INFINITY so we do not need a conversion even.
+ */
+ error = copyin(args->new, &nrlim, sizeof(nrlim));
+ if (error != 0)
+ return (error);
+ }
+
+ flags = PGET_HOLD | PGET_NOTWEXIT;
+ if (args->new != NULL)
+ flags |= PGET_CANDEBUG;
+ else
+ flags |= PGET_CANSEE;
+ error = pget(args->pid, flags, &p);
+ if (error != 0)
+ return (error);
+
+ if (args->old != NULL) {
+ PROC_LOCK(p);
+ lim_rlimit_proc(p, which, &rlim);
+ PROC_UNLOCK(p);
+ if (rlim.rlim_cur == RLIM_INFINITY)
+ lrlim.rlim_cur = LINUX_RLIM_INFINITY;
+ else
+ lrlim.rlim_cur = rlim.rlim_cur;
+ if (rlim.rlim_max == RLIM_INFINITY)
+ lrlim.rlim_max = LINUX_RLIM_INFINITY;
+ else
+ lrlim.rlim_max = rlim.rlim_max;
+ error = copyout(&lrlim, args->old, sizeof(lrlim));
+ if (error != 0)
+ goto out;
+ }
+
+ if (args->new != NULL)
+ error = kern_proc_setrlimit(td, p, which, &nrlim);
+
+ out:
+ PRELE(p);
+ return (error);
+}
+
+int
+linux_pselect6(struct thread *td, struct linux_pselect6_args *args)
+{
+ struct timeval utv, tv0, tv1, *tvp;
+ struct l_pselect6arg lpse6;
+ struct l_timespec lts;
+ struct timespec uts;
+ l_sigset_t l_ss;
+ sigset_t *ssp;
+ sigset_t ss;
+ int error;
+
+ ssp = NULL;
+ if (args->sig != NULL) {
+ error = copyin(args->sig, &lpse6, sizeof(lpse6));
+ if (error != 0)
+ return (error);
+ if (lpse6.ss_len != sizeof(l_ss))
+ return (EINVAL);
+ if (lpse6.ss != 0) {
+ error = copyin(PTRIN(lpse6.ss), &l_ss,
+ sizeof(l_ss));
+ if (error != 0)
+ return (error);
+ linux_to_bsd_sigset(&l_ss, &ss);
+ ssp = &ss;
+ }
+ }
+
+ /*
+ * Currently glibc changes nanosecond number to microsecond.
+ * This mean losing precision but for now it is hardly seen.
+ */
+ if (args->tsp != NULL) {
+ error = copyin(args->tsp, &lts, sizeof(lts));
+ if (error != 0)
+ return (error);
+ error = linux_to_native_timespec(&uts, &lts);
+ if (error != 0)
+ return (error);
+
+ TIMESPEC_TO_TIMEVAL(&utv, &uts);
+ if (itimerfix(&utv))
+ return (EINVAL);
+
+ microtime(&tv0);
+ tvp = &utv;
+ } else
+ tvp = NULL;
+
+ error = kern_pselect(td, args->nfds, args->readfds, args->writefds,
+ args->exceptfds, tvp, ssp, LINUX_NFDBITS);
+
+ if (error == 0 && args->tsp != NULL) {
+ if (td->td_retval[0] != 0) {
+ /*
+ * Compute how much time was left of the timeout,
+ * by subtracting the current time and the time
+ * before we started the call, and subtracting
+ * that result from the user-supplied value.
+ */
+
+ microtime(&tv1);
+ timevalsub(&tv1, &tv0);
+ timevalsub(&utv, &tv1);
+ if (utv.tv_sec < 0)
+ timevalclear(&utv);
+ } else
+ timevalclear(&utv);
+
+ TIMEVAL_TO_TIMESPEC(&utv, &uts);
+
+ native_to_linux_timespec(&lts, &uts);
+ error = copyout(&lts, args->tsp, sizeof(lts));
+ }
+
+ return (error);
+}
+
+int
+linux_ppoll(struct thread *td, struct linux_ppoll_args *args)
+{
+ struct timespec ts0, ts1;
+ struct l_timespec lts;
+ struct timespec uts, *tsp;
+ l_sigset_t l_ss;
+ sigset_t *ssp;
+ sigset_t ss;
+ int error;
+
+ if (args->sset != NULL) {
+ if (args->ssize != sizeof(l_ss))
+ return (EINVAL);
+ error = copyin(args->sset, &l_ss, sizeof(l_ss));
+ if (error)
+ return (error);
+ linux_to_bsd_sigset(&l_ss, &ss);
+ ssp = &ss;
+ } else
+ ssp = NULL;
+ if (args->tsp != NULL) {
+ error = copyin(args->tsp, &lts, sizeof(lts));
+ if (error)
+ return (error);
+ error = linux_to_native_timespec(&uts, &lts);
+ if (error != 0)
+ return (error);
+
+ nanotime(&ts0);
+ tsp = &uts;
+ } else
+ tsp = NULL;
+
+ error = kern_poll(td, args->fds, args->nfds, tsp, ssp);
+
+ if (error == 0 && args->tsp != NULL) {
+ if (td->td_retval[0]) {
+ nanotime(&ts1);
+ timespecsub(&ts1, &ts0);
+ timespecsub(&uts, &ts1);
+ if (uts.tv_sec < 0)
+ timespecclear(&uts);
+ } else
+ timespecclear(&uts);
+
+ native_to_linux_timespec(&lts, &uts);
+ error = copyout(&lts, args->tsp, sizeof(lts));
+ }
+
+ return (error);
+}
+
+#if defined(DEBUG) || defined(KTR)
+/* XXX: can be removed when every ldebug(...) and KTR stuff are removed. */
+
+u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))];
+
+static int
+linux_debug(int syscall, int toggle, int global)
+{
+
+ if (global) {
+ char c = toggle ? 0 : 0xff;
+
+ memset(linux_debug_map, c, sizeof(linux_debug_map));
+ return (0);
+ }
+ if (syscall < 0 || syscall >= LINUX_SYS_MAXSYSCALL)
+ return (EINVAL);
+ if (toggle)
+ clrbit(linux_debug_map, syscall);
+ else
+ setbit(linux_debug_map, syscall);
+ return (0);
+}
+
+/*
+ * Usage: sysctl linux.debug=<syscall_nr>.<0/1>
+ *
+ * E.g.: sysctl linux.debug=21.0
+ *
+ * As a special case, syscall "all" will apply to all syscalls globally.
+ */
+#define LINUX_MAX_DEBUGSTR 16
+int
+linux_sysctl_debug(SYSCTL_HANDLER_ARGS)
+{
+ char value[LINUX_MAX_DEBUGSTR], *p;
+ int error, sysc, toggle;
+ int global = 0;
+
+ value[0] = '\0';
+ error = sysctl_handle_string(oidp, value, LINUX_MAX_DEBUGSTR, req);
+ if (error || req->newptr == NULL)
+ return (error);
+ for (p = value; *p != '\0' && *p != '.'; p++);
+ if (*p == '\0')
+ return (EINVAL);
+ *p++ = '\0';
+ sysc = strtol(value, NULL, 0);
+ toggle = strtol(p, NULL, 0);
+ if (strcmp(value, "all") == 0)
+ global = 1;
+ error = linux_debug(sysc, toggle, global);
+ return (error);
+}
+
+#endif /* DEBUG || KTR */
+
+int
+linux_sched_rr_get_interval(struct thread *td,
+ struct linux_sched_rr_get_interval_args *uap)
+{
+ struct timespec ts;
+ struct l_timespec lts;
+ struct thread *tdt;
+ int error;
+
+ /*
+ * According to man in case the invalid pid specified
+ * EINVAL should be returned.
+ */
+ if (uap->pid < 0)
+ return (EINVAL);
+
+ tdt = linux_tdfind(td, uap->pid, -1);
+ if (tdt == NULL)
+ return (ESRCH);
+
+ error = kern_sched_rr_get_interval_td(td, tdt, &ts);
+ PROC_UNLOCK(tdt->td_proc);
+ if (error != 0)
+ return (error);
+ native_to_linux_timespec(&lts, &ts);
+ return (copyout(&lts, uap->interval, sizeof(lts)));
+}
+
+/*
+ * In case when the Linux thread is the initial thread in
+ * the thread group thread id is equal to the process id.
+ * Glibc depends on this magic (assert in pthread_getattr_np.c).
+ */
+struct thread *
+linux_tdfind(struct thread *td, lwpid_t tid, pid_t pid)
+{
+ struct linux_emuldata *em;
+ struct thread *tdt;
+ struct proc *p;
+
+ tdt = NULL;
+ if (tid == 0 || tid == td->td_tid) {
+ tdt = td;
+ PROC_LOCK(tdt->td_proc);
+ } else if (tid > PID_MAX)
+ tdt = tdfind(tid, pid);
+ else {
+ /*
+ * Initial thread where the tid equal to the pid.
+ */
+ p = pfind(tid);
+ if (p != NULL) {
+ if (SV_PROC_ABI(p) != SV_ABI_LINUX) {
+ /*
+ * p is not a Linuxulator process.
+ */
+ PROC_UNLOCK(p);
+ return (NULL);
+ }
+ FOREACH_THREAD_IN_PROC(p, tdt) {
+ em = em_find(tdt);
+ if (tid == em->em_tid)
+ return (tdt);
+ }
+ PROC_UNLOCK(p);
+ }
+ return (NULL);
+ }
+
+ return (tdt);
+}
+
+void
+linux_to_bsd_waitopts(int options, int *bsdopts)
+{
+
+ if (options & LINUX_WNOHANG)
+ *bsdopts |= WNOHANG;
+ if (options & LINUX_WUNTRACED)
+ *bsdopts |= WUNTRACED;
+ if (options & LINUX_WEXITED)
+ *bsdopts |= WEXITED;
+ if (options & LINUX_WCONTINUED)
+ *bsdopts |= WCONTINUED;
+ if (options & LINUX_WNOWAIT)
+ *bsdopts |= WNOWAIT;
+
+ if (options & __WCLONE)
+ *bsdopts |= WLINUXCLONE;
+}
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
index 51135d8dd629..08bc85fd936c 100644
--- a/sys/compat/linux/linux_misc.h
+++ b/sys/compat/linux/linux_misc.h
@@ -31,6 +31,11 @@
#ifndef _LINUX_MISC_H_
#define _LINUX_MISC_H_
+#include <sys/sysctl.h>
+
+ /* bits per mask */
+#define LINUX_NFDBITS sizeof(l_fd_mask) * 8
+
/*
* Miscellaneous
*/
@@ -57,7 +62,7 @@
#define LINUX_PATH_MAX 4096
-extern const char *linux_platform;
+extern const char *linux_kplatform;
/*
* Non-standard aux entry types used in Linux ELF binaries.
@@ -70,7 +75,12 @@ extern const char *linux_platform;
#define LINUX_AT_BASE_PLATFORM 24 /* string identifying real platform, may
* differ from AT_PLATFORM.
*/
+#define LINUX_AT_RANDOM 25 /* address of random bytes */
#define LINUX_AT_EXECFN 31 /* filename of program */
+#define LINUX_AT_SYSINFO 32 /* vsyscall */
+#define LINUX_AT_SYSINFO_EHDR 33 /* vdso header */
+
+#define LINUX_AT_RANDOM_LEN 16 /* size of random bytes */
/* Linux sets the i387 to extended precision. */
#if defined(__i386__) || defined(__amd64__)
@@ -90,10 +100,6 @@ extern const char *linux_platform;
#define LINUX_CLONE_CHILD_CLEARTID 0x00200000
#define LINUX_CLONE_CHILD_SETTID 0x01000000
-#define LINUX_THREADING_FLAGS \
- (LINUX_CLONE_VM | LINUX_CLONE_FS | LINUX_CLONE_FILES | \
- LINUX_CLONE_SIGHAND | LINUX_CLONE_THREAD)
-
/* Scheduling policies */
#define LINUX_SCHED_OTHER 0
#define LINUX_SCHED_FIFO 1
@@ -115,13 +121,37 @@ struct l_new_utsname {
#define LINUX_CLOCK_REALTIME_HR 4
#define LINUX_CLOCK_MONOTONIC_HR 5
+#define LINUX_UTIME_NOW 0x3FFFFFFF
+#define LINUX_UTIME_OMIT 0x3FFFFFFE
+
extern int stclohz;
-#define __WCLONE 0x80000000
+#define LINUX_WNOHANG 0x00000001
+#define LINUX_WUNTRACED 0x00000002
+#define LINUX_WSTOPPED LINUX_WUNTRACED
+#define LINUX_WEXITED 0x00000004
+#define LINUX_WCONTINUED 0x00000008
+#define LINUX_WNOWAIT 0x01000000
+
+
+#define __WNOTHREAD 0x20000000
+#define __WALL 0x40000000
+#define __WCLONE 0x80000000
+
+/* Linux waitid idtype */
+#define LINUX_P_ALL 0
+#define LINUX_P_PID 1
+#define LINUX_P_PGID 2
+
+#define LINUX_RLIM_INFINITY (~0UL)
int linux_common_wait(struct thread *td, int pid, int *status,
int options, struct rusage *ru);
+void linux_to_bsd_waitopts(int options, int *bsdopts);
int linux_set_upcall_kse(struct thread *td, register_t stack);
int linux_set_cloned_tls(struct thread *td, void *desc);
+struct thread *linux_tdfind(struct thread *, lwpid_t, pid_t);
+
+int linux_sysctl_debug(SYSCTL_HANDLER_ARGS);
#endif /* _LINUX_MISC_H_ */
diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
index 1c778f9fba7b..0ecf537467c3 100644
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -53,40 +53,12 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.h>
#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_misc.h>
-void
-linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
-{
- int b, l;
-
- SIGEMPTYSET(*bss);
- bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
- bss->__bits[1] = lss->__bits[1];
- for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
- if (LINUX_SIGISMEMBER(*lss, l)) {
- b = linux_to_bsd_signal[_SIG_IDX(l)];
- if (b)
- SIGADDSET(*bss, b);
- }
- }
-}
+static int linux_do_tkill(struct thread *td, struct thread *tdt,
+ ksiginfo_t *ksi);
+static void sicode_to_lsicode(int si_code, int *lsi_code);
-void
-bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
-{
- int b, l;
-
- LINUX_SIGEMPTYSET(*lss);
- lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
- lss->__bits[1] = bss->__bits[1];
- for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
- if (SIGISMEMBER(*bss, b)) {
- l = bsd_to_linux_signal[_SIG_IDX(b)];
- if (l)
- LINUX_SIGADDSET(*lss, l);
- }
- }
-}
static void
linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
@@ -155,11 +127,7 @@ linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
linux_to_bsd_sigaction(linux_nsa, nsa);
} else
nsa = NULL;
-
- if (linux_sig <= LINUX_SIGTBLSZ)
- sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
- else
- sig = linux_sig;
+ sig = linux_to_bsd_signal(linux_sig);
error = kern_sigaction(td, sig, nsa, osa, 0);
if (error)
@@ -171,7 +139,7 @@ linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
return (0);
}
-
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_signal(struct thread *td, struct linux_signal_args *args)
{
@@ -193,6 +161,7 @@ linux_signal(struct thread *td, struct linux_signal_args *args)
return (error);
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args)
@@ -262,6 +231,7 @@ linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new,
return (error);
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
{
@@ -279,7 +249,7 @@ linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
if (error)
return (error);
LINUX_SIGEMPTYSET(set);
- set.__bits[0] = mask;
+ set.__mask = mask;
}
error = linux_do_sigprocmask(td, args->how,
@@ -287,12 +257,13 @@ linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
args->omask ? &oset : NULL);
if (args->omask != NULL && !error) {
- mask = oset.__bits[0];
+ mask = oset.__mask;
error = copyout(&mask, args->omask, sizeof(l_osigset_t));
}
return (error);
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
@@ -327,6 +298,7 @@ linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
return (error);
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
int
linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
{
@@ -341,7 +313,7 @@ linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
PROC_LOCK(p);
bsd_to_linux_sigset(&td->td_sigmask, &mask);
PROC_UNLOCK(p);
- td->td_retval[0] = mask.__bits[0];
+ td->td_retval[0] = mask.__mask;
return (0);
}
@@ -359,9 +331,9 @@ linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
PROC_LOCK(p);
bsd_to_linux_sigset(&td->td_sigmask, &lset);
- td->td_retval[0] = lset.__bits[0];
+ td->td_retval[0] = lset.__mask;
LINUX_SIGEMPTYSET(lset);
- lset.__bits[0] = args->mask;
+ lset.__mask = args->mask;
linux_to_bsd_sigset(&lset, &bset);
td->td_sigmask = bset;
SIG_CANTMASK(td->td_sigmask);
@@ -370,9 +342,6 @@ linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
return (0);
}
-/*
- * MPSAFE
- */
int
linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
{
@@ -392,9 +361,10 @@ linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
SIGSETAND(bset, td->td_sigmask);
PROC_UNLOCK(p);
bsd_to_linux_sigset(&bset, &lset);
- mask = lset.__bits[0];
+ mask = lset.__mask;
return (copyout(&mask, args->mask, sizeof(mask)));
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
/*
* MPSAFE
@@ -458,8 +428,8 @@ linux_rt_sigtimedwait(struct thread *td,
#ifdef DEBUG
if (ldebug(rt_sigtimedwait))
printf(LMSG("linux_rt_sigtimedwait: "
- "incoming timeout (%d/%d)\n"),
- ltv.tv_sec, ltv.tv_usec);
+ "incoming timeout (%jd/%jd)\n"),
+ (intmax_t)ltv.tv_sec, (intmax_t)ltv.tv_usec);
#endif
tv.tv_sec = (long)ltv.tv_sec;
tv.tv_usec = (suseconds_t)ltv.tv_usec;
@@ -495,7 +465,7 @@ linux_rt_sigtimedwait(struct thread *td,
if (error)
return (error);
- sig = BSD_TO_LINUX_SIGNAL(info.ksi_signo);
+ sig = bsd_to_linux_signal(info.ksi_signo);
if (args->ptr) {
memset(&linfo, 0, sizeof(linfo));
@@ -527,66 +497,31 @@ linux_kill(struct thread *td, struct linux_kill_args *args)
if (!LINUX_SIG_VALID(args->signum) && args->signum != 0)
return (EINVAL);
- if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
- tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
+ if (args->signum > 0)
+ tmp.signum = linux_to_bsd_signal(args->signum);
else
- tmp.signum = args->signum;
+ tmp.signum = 0;
tmp.pid = args->pid;
return (sys_kill(td, &tmp));
}
static int
-linux_do_tkill(struct thread *td, l_int tgid, l_int pid, l_int signum)
+linux_do_tkill(struct thread *td, struct thread *tdt, ksiginfo_t *ksi)
{
- struct proc *proc = td->td_proc;
- struct linux_emuldata *em;
struct proc *p;
- ksiginfo_t ksi;
int error;
- AUDIT_ARG_SIGNUM(signum);
- AUDIT_ARG_PID(pid);
-
- /*
- * Allow signal 0 as a means to check for privileges
- */
- if (!LINUX_SIG_VALID(signum) && signum != 0)
- return (EINVAL);
-
- if (signum > 0 && signum <= LINUX_SIGTBLSZ)
- signum = linux_to_bsd_signal[_SIG_IDX(signum)];
-
- if ((p = pfind(pid)) == NULL) {
- if ((p = zpfind(pid)) == NULL)
- return (ESRCH);
- }
-
+ p = tdt->td_proc;
+ AUDIT_ARG_SIGNUM(ksi->ksi_signo);
+ AUDIT_ARG_PID(p->p_pid);
AUDIT_ARG_PROCESS(p);
- error = p_cansignal(td, p, signum);
- if (error != 0 || signum == 0)
- goto out;
-
- error = ESRCH;
- em = em_find(p, EMUL_DONTLOCK);
- if (em == NULL) {
-#ifdef DEBUG
- printf("emuldata not found in do_tkill.\n");
-#endif
+ error = p_cansignal(td, p, ksi->ksi_signo);
+ if (error != 0 || ksi->ksi_signo == 0)
goto out;
- }
- if (tgid > 0 && em->shared->group_pid != tgid)
- goto out;
-
- ksiginfo_init(&ksi);
- ksi.ksi_signo = signum;
- ksi.ksi_code = LINUX_SI_TKILL;
- ksi.ksi_errno = 0;
- ksi.ksi_pid = proc->p_pid;
- ksi.ksi_uid = proc->p_ucred->cr_ruid;
- error = pksignal(p, ksi.ksi_signo, &ksi);
+ tdksignal(tdt, ksi->ksi_signo, ksi);
out:
PROC_UNLOCK(p);
@@ -596,20 +531,53 @@ out:
int
linux_tgkill(struct thread *td, struct linux_tgkill_args *args)
{
+ struct thread *tdt;
+ ksiginfo_t ksi;
+ int sig;
#ifdef DEBUG
if (ldebug(tgkill))
- printf(ARGS(tgkill, "%d, %d, %d"), args->tgid, args->pid, args->sig);
+ printf(ARGS(tgkill, "%d, %d, %d"),
+ args->tgid, args->pid, args->sig);
#endif
+
if (args->pid <= 0 || args->tgid <=0)
return (EINVAL);
- return (linux_do_tkill(td, args->tgid, args->pid, args->sig));
+ /*
+ * Allow signal 0 as a means to check for privileges
+ */
+ if (!LINUX_SIG_VALID(args->sig) && args->sig != 0)
+ return (EINVAL);
+
+ if (args->sig > 0)
+ sig = linux_to_bsd_signal(args->sig);
+ else
+ sig = 0;
+
+ tdt = linux_tdfind(td, args->pid, args->tgid);
+ if (tdt == NULL)
+ return (ESRCH);
+
+ ksiginfo_init(&ksi);
+ ksi.ksi_signo = sig;
+ ksi.ksi_code = SI_LWP;
+ ksi.ksi_errno = 0;
+ ksi.ksi_pid = td->td_proc->p_pid;
+ ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid;
+ return (linux_do_tkill(td, tdt, &ksi));
}
+/*
+ * Deprecated since 2.5.75. Replaced by tgkill().
+ */
int
linux_tkill(struct thread *td, struct linux_tkill_args *args)
{
+ struct thread *tdt;
+ ksiginfo_t ksi;
+ int sig;
+
#ifdef DEBUG
if (ldebug(tkill))
printf(ARGS(tkill, "%i, %i"), args->tid, args->sig);
@@ -617,40 +585,182 @@ linux_tkill(struct thread *td, struct linux_tkill_args *args)
if (args->tid <= 0)
return (EINVAL);
- return (linux_do_tkill(td, 0, args->tid, args->sig));
+ if (!LINUX_SIG_VALID(args->sig))
+ return (EINVAL);
+
+ sig = linux_to_bsd_signal(args->sig);
+
+ tdt = linux_tdfind(td, args->tid, -1);
+ if (tdt == NULL)
+ return (ESRCH);
+
+ ksiginfo_init(&ksi);
+ ksi.ksi_signo = sig;
+ ksi.ksi_code = SI_LWP;
+ ksi.ksi_errno = 0;
+ ksi.ksi_pid = td->td_proc->p_pid;
+ ksi.ksi_uid = td->td_proc->p_ucred->cr_ruid;
+ return (linux_do_tkill(td, tdt, &ksi));
+}
+
+void
+ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig)
+{
+
+ siginfo_to_lsiginfo(&ksi->ksi_info, lsi, sig);
+}
+
+static void
+sicode_to_lsicode(int si_code, int *lsi_code)
+{
+
+ switch (si_code) {
+ case SI_USER:
+ *lsi_code = LINUX_SI_USER;
+ break;
+ case SI_KERNEL:
+ *lsi_code = LINUX_SI_KERNEL;
+ break;
+ case SI_QUEUE:
+ *lsi_code = LINUX_SI_QUEUE;
+ break;
+ case SI_TIMER:
+ *lsi_code = LINUX_SI_TIMER;
+ break;
+ case SI_MESGQ:
+ *lsi_code = LINUX_SI_MESGQ;
+ break;
+ case SI_ASYNCIO:
+ *lsi_code = LINUX_SI_ASYNCIO;
+ break;
+ case SI_LWP:
+ *lsi_code = LINUX_SI_TKILL;
+ break;
+ default:
+ *lsi_code = si_code;
+ break;
+ }
}
void
-ksiginfo_to_lsiginfo(ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig)
+siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig)
{
+ /* sig alredy converted */
lsi->lsi_signo = sig;
- lsi->lsi_code = ksi->ksi_code;
+ sicode_to_lsicode(si->si_code, &lsi->lsi_code);
- switch (sig) {
- case LINUX_SIGPOLL:
- /* XXX si_fd? */
- lsi->lsi_band = ksi->ksi_band;
+ switch (si->si_code) {
+ case SI_LWP:
+ lsi->lsi_pid = si->si_pid;
+ lsi->lsi_uid = si->si_uid;
break;
- case LINUX_SIGCHLD:
- lsi->lsi_pid = ksi->ksi_pid;
- lsi->lsi_uid = ksi->ksi_uid;
- lsi->lsi_status = ksi->ksi_status;
+
+ case SI_TIMER:
+ lsi->lsi_int = si->si_value.sival_int;
+ lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
+ lsi->lsi_tid = si->si_timerid;
break;
- case LINUX_SIGBUS:
- case LINUX_SIGILL:
- case LINUX_SIGFPE:
- case LINUX_SIGSEGV:
- lsi->lsi_addr = PTROUT(ksi->ksi_addr);
+
+ case SI_QUEUE:
+ lsi->lsi_pid = si->si_pid;
+ lsi->lsi_uid = si->si_uid;
+ lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
break;
+
+ case SI_ASYNCIO:
+ lsi->lsi_int = si->si_value.sival_int;
+ lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
+ break;
+
default:
- /* XXX SI_TIMER etc... */
- lsi->lsi_pid = ksi->ksi_pid;
- lsi->lsi_uid = ksi->ksi_uid;
+ switch (sig) {
+ case LINUX_SIGPOLL:
+ /* XXX si_fd? */
+ lsi->lsi_band = si->si_band;
+ break;
+
+ case LINUX_SIGCHLD:
+ lsi->lsi_errno = 0;
+ lsi->lsi_pid = si->si_pid;
+ lsi->lsi_uid = si->si_uid;
+
+ if (si->si_code == CLD_STOPPED)
+ lsi->lsi_status = bsd_to_linux_signal(si->si_status);
+ else if (si->si_code == CLD_CONTINUED)
+ lsi->lsi_status = bsd_to_linux_signal(SIGCONT);
+ else
+ lsi->lsi_status = si->si_status;
+ break;
+
+ case LINUX_SIGBUS:
+ case LINUX_SIGILL:
+ case LINUX_SIGFPE:
+ case LINUX_SIGSEGV:
+ lsi->lsi_addr = PTROUT(si->si_addr);
+ break;
+
+ default:
+ lsi->lsi_pid = si->si_pid;
+ lsi->lsi_uid = si->si_uid;
+ if (sig >= LINUX_SIGRTMIN) {
+ lsi->lsi_int = si->si_value.sival_int;
+ lsi->lsi_ptr = PTROUT(si->si_value.sival_ptr);
+ }
+ break;
+ }
break;
}
- if (sig >= LINUX_SIGRTMIN) {
- lsi->lsi_int = ksi->ksi_info.si_value.sival_int;
- lsi->lsi_ptr = PTROUT(ksi->ksi_info.si_value.sival_ptr);
+}
+
+void
+lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig)
+{
+
+ ksi->ksi_signo = sig;
+ ksi->ksi_code = lsi->lsi_code; /* XXX. Convert. */
+ ksi->ksi_pid = lsi->lsi_pid;
+ ksi->ksi_uid = lsi->lsi_uid;
+ ksi->ksi_status = lsi->lsi_status;
+ ksi->ksi_addr = PTRIN(lsi->lsi_addr);
+ ksi->ksi_info.si_value.sival_int = lsi->lsi_int;
+}
+
+int
+linux_rt_sigqueueinfo(struct thread *td, struct linux_rt_sigqueueinfo_args *args)
+{
+ l_siginfo_t linfo;
+ struct proc *p;
+ ksiginfo_t ksi;
+ int error;
+ int sig;
+
+ if (!LINUX_SIG_VALID(args->sig))
+ return (EINVAL);
+
+ error = copyin(args->info, &linfo, sizeof(linfo));
+ if (error != 0)
+ return (error);
+
+ if (linfo.lsi_code >= 0)
+ return (EPERM);
+
+ sig = linux_to_bsd_signal(args->sig);
+
+ error = ESRCH;
+ if ((p = pfind(args->pid)) != NULL ||
+ (p = zpfind(args->pid)) != NULL) {
+ error = p_cansignal(td, p, sig);
+ if (error != 0) {
+ PROC_UNLOCK(p);
+ return (error);
+ }
+
+ ksiginfo_init(&ksi);
+ lsiginfo_to_ksiginfo(&linfo, &ksi, sig);
+ error = tdsendsignal(p, NULL, sig, &ksi);
+ PROC_UNLOCK(p);
}
+
+ return (error);
}
diff --git a/sys/compat/linux/linux_signal.h b/sys/compat/linux/linux_signal.h
index 426cf43566cb..510bfb38397c 100644
--- a/sys/compat/linux/linux_signal.h
+++ b/sys/compat/linux/linux_signal.h
@@ -31,19 +31,21 @@
#ifndef _LINUX_SIGNAL_H_
#define _LINUX_SIGNAL_H_
-#define LINUX_SI_TKILL -6;
-
-extern int bsd_to_linux_signal[];
-extern int linux_to_bsd_signal[];
+/*
+ * si_code values
+ */
+#define LINUX_SI_USER 0 /* sent by kill, sigsend, raise */
+#define LINUX_SI_KERNEL 0x80 /* sent by the kernel from somewhere */
+#define LINUX_SI_QUEUE -1 /* sent by sigqueue */
+#define LINUX_SI_TIMER -2 /* sent by timer expiration */
+#define LINUX_SI_MESGQ -3 /* sent by real time mesq state change */
+#define LINUX_SI_ASYNCIO -4 /* sent by AIO completion */
+#define LINUX_SI_SIGIO -5 /* sent by queued SIGIO */
+#define LINUX_SI_TKILL -6 /* sent by tkill system call */
-void linux_to_bsd_sigset(l_sigset_t *, sigset_t *);
-void bsd_to_linux_sigset(sigset_t *, l_sigset_t *);
int linux_do_sigaction(struct thread *, int, l_sigaction_t *, l_sigaction_t *);
-void ksiginfo_to_lsiginfo(ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig);
-
-#define LINUX_SIG_VALID(sig) ((sig) <= LINUX_NSIG && (sig) > 0)
-
-#define BSD_TO_LINUX_SIGNAL(sig) \
- (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig)
+void ksiginfo_to_lsiginfo(const ksiginfo_t *ksi, l_siginfo_t *lsi, l_int sig);
+void siginfo_to_lsiginfo(const siginfo_t *si, l_siginfo_t *lsi, l_int sig);
+void lsiginfo_to_ksiginfo(const l_siginfo_t *lsi, ksiginfo_t *ksi, int sig);
#endif /* _LINUX_SIGNAL_H_ */
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index f43378795244..34d69ff7626d 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -70,10 +70,17 @@ __FBSDID("$FreeBSD$");
#include <machine/../linux/linux.h>
#include <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_file.h>
#include <compat/linux/linux_socket.h>
+#include <compat/linux/linux_timer.h>
#include <compat/linux/linux_util.h>
static int linux_to_bsd_domain(int);
+static int linux_sendmsg_common(struct thread *, l_int, struct l_msghdr *,
+ l_uint);
+static int linux_recvmsg_common(struct thread *, l_int, struct l_msghdr *,
+ l_uint, struct msghdr *);
+static int linux_set_socket_flags(int, int *);
/*
* Reads a linux sockaddr and does any necessary translation.
@@ -428,7 +435,6 @@ linux_to_bsd_sockaddr(struct sockaddr *arg, int len)
return (error);
}
-
static int
linux_sa_put(struct osockaddr *osa)
{
@@ -477,6 +483,8 @@ bsd_to_linux_cmsg_type(int cmsg_type)
return (LINUX_SCM_RIGHTS);
case SCM_CREDS:
return (LINUX_SCM_CREDENTIALS);
+ case SCM_TIMESTAMP:
+ return (LINUX_SCM_TIMESTAMP);
}
return (-1);
}
@@ -529,20 +537,15 @@ bsd_to_linux_msghdr(const struct msghdr *bhdr, struct l_msghdr *lhdr)
}
static int
-linux_set_socket_flags(struct thread *td, int s, int flags)
+linux_set_socket_flags(int lflags, int *flags)
{
- int error;
- if (flags & LINUX_SOCK_NONBLOCK) {
- error = kern_fcntl(td, s, F_SETFL, O_NONBLOCK);
- if (error)
- return (error);
- }
- if (flags & LINUX_SOCK_CLOEXEC) {
- error = kern_fcntl(td, s, F_SETFD, FD_CLOEXEC);
- if (error)
- return (error);
- }
+ if (lflags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
+ return (EINVAL);
+ if (lflags & LINUX_SOCK_NONBLOCK)
+ *flags |= SOCK_NONBLOCK;
+ if (lflags & LINUX_SOCK_CLOEXEC)
+ *flags |= SOCK_CLOEXEC;
return (0);
}
@@ -585,15 +588,6 @@ linux_check_hdrincl(struct thread *td, int s)
return (optval == 0);
}
-struct linux_sendto_args {
- int s;
- l_uintptr_t msg;
- int len;
- int flags;
- l_uintptr_t to;
- int tolen;
-};
-
/*
* Updated sendto() when IP_HDRINCL is set:
* tweak endian-dependent fields in the IP packet.
@@ -618,7 +612,7 @@ linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args)
linux_args->len > IP_MAXPACKET)
return (EINVAL);
- packet = (struct ip *)malloc(linux_args->len, M_TEMP, M_WAITOK);
+ packet = (struct ip *)malloc(linux_args->len, M_LINUX, M_WAITOK);
/* Make kernel copy of the packet to be sent */
if ((error = copyin(PTRIN(linux_args->msg), packet,
@@ -641,17 +635,11 @@ linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args)
error = linux_sendit(td, linux_args->s, &msg, linux_args->flags,
NULL, UIO_SYSSPACE);
goout:
- free(packet, M_TEMP);
+ free(packet, M_LINUX);
return (error);
}
-struct linux_socket_args {
- int domain;
- int type;
- int protocol;
-};
-
-static int
+int
linux_socket(struct thread *td, struct linux_socket_args *args)
{
struct socket_args /* {
@@ -659,15 +647,16 @@ linux_socket(struct thread *td, struct linux_socket_args *args)
int type;
int protocol;
} */ bsd_args;
- int retval_socket, socket_flags;
+ int retval_socket;
bsd_args.protocol = args->protocol;
- socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK;
- if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
- return (EINVAL);
bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK;
if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX)
return (EINVAL);
+ retval_socket = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK,
+ &bsd_args.type);
+ if (retval_socket != 0)
+ return (retval_socket);
bsd_args.domain = linux_to_bsd_domain(args->domain);
if (bsd_args.domain == -1)
return (EAFNOSUPPORT);
@@ -676,13 +665,6 @@ linux_socket(struct thread *td, struct linux_socket_args *args)
if (retval_socket)
return (retval_socket);
- retval_socket = linux_set_socket_flags(td, td->td_retval[0],
- socket_flags);
- if (retval_socket) {
- (void)kern_close(td, td->td_retval[0]);
- goto out;
- }
-
if (bsd_args.type == SOCK_RAW
&& (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0)
&& bsd_args.domain == PF_INET) {
@@ -711,17 +693,10 @@ linux_socket(struct thread *td, struct linux_socket_args *args)
}
#endif
-out:
return (retval_socket);
}
-struct linux_bind_args {
- int s;
- l_uintptr_t name;
- int namelen;
-};
-
-static int
+int
linux_bind(struct thread *td, struct linux_bind_args *args)
{
struct sockaddr *sa;
@@ -739,13 +714,6 @@ linux_bind(struct thread *td, struct linux_bind_args *args)
return (error);
}
-struct linux_connect_args {
- int s;
- l_uintptr_t name;
- int namelen;
-};
-int linux_connect(struct thread *, struct linux_connect_args *);
-
int
linux_connect(struct thread *td, struct linux_connect_args *args)
{
@@ -790,12 +758,7 @@ linux_connect(struct thread *td, struct linux_connect_args *args)
return (error);
}
-struct linux_listen_args {
- int s;
- int backlog;
-};
-
-static int
+int
linux_listen(struct thread *td, struct linux_listen_args *args)
{
struct listen_args /* {
@@ -812,43 +775,31 @@ static int
linux_accept_common(struct thread *td, int s, l_uintptr_t addr,
l_uintptr_t namelen, int flags)
{
- struct accept_args /* {
+ struct accept4_args /* {
int s;
struct sockaddr * __restrict name;
socklen_t * __restrict anamelen;
+ int flags;
} */ bsd_args;
int error;
- if (flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
- return (EINVAL);
-
bsd_args.s = s;
/* XXX: */
bsd_args.name = (struct sockaddr * __restrict)PTRIN(addr);
bsd_args.anamelen = PTRIN(namelen);/* XXX */
- error = sys_accept(td, &bsd_args);
+ bsd_args.flags = 0;
+ error = linux_set_socket_flags(flags, &bsd_args.flags);
+ if (error != 0)
+ return (error);
+ error = sys_accept4(td, &bsd_args);
bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name);
if (error) {
if (error == EFAULT && namelen != sizeof(struct sockaddr_in))
return (EINVAL);
return (error);
}
-
- /*
- * linux appears not to copy flags from the parent socket to the
- * accepted one, so we must clear the flags in the new descriptor
- * and apply the requested flags.
- */
- error = kern_fcntl(td, td->td_retval[0], F_SETFL, 0);
- if (error)
- goto out;
- error = linux_set_socket_flags(td, td->td_retval[0], flags);
- if (error)
- goto out;
if (addr)
error = linux_sa_put(PTRIN(addr));
-
-out:
if (error) {
(void)kern_close(td, td->td_retval[0]);
td->td_retval[0] = 0;
@@ -856,13 +807,7 @@ out:
return (error);
}
-struct linux_accept_args {
- int s;
- l_uintptr_t addr;
- l_uintptr_t namelen;
-};
-
-static int
+int
linux_accept(struct thread *td, struct linux_accept_args *args)
{
@@ -870,14 +815,7 @@ linux_accept(struct thread *td, struct linux_accept_args *args)
args->namelen, 0));
}
-struct linux_accept4_args {
- int s;
- l_uintptr_t addr;
- l_uintptr_t namelen;
- int flags;
-};
-
-static int
+int
linux_accept4(struct thread *td, struct linux_accept4_args *args)
{
@@ -885,13 +823,7 @@ linux_accept4(struct thread *td, struct linux_accept4_args *args)
args->namelen, args->flags));
}
-struct linux_getsockname_args {
- int s;
- l_uintptr_t addr;
- l_uintptr_t namelen;
-};
-
-static int
+int
linux_getsockname(struct thread *td, struct linux_getsockname_args *args)
{
struct getsockname_args /* {
@@ -915,13 +847,7 @@ linux_getsockname(struct thread *td, struct linux_getsockname_args *args)
return (0);
}
-struct linux_getpeername_args {
- int s;
- l_uintptr_t addr;
- l_uintptr_t namelen;
-};
-
-static int
+int
linux_getpeername(struct thread *td, struct linux_getpeername_args *args)
{
struct getpeername_args /* {
@@ -944,14 +870,7 @@ linux_getpeername(struct thread *td, struct linux_getpeername_args *args)
return (0);
}
-struct linux_socketpair_args {
- int domain;
- int type;
- int protocol;
- l_uintptr_t rsv;
-};
-
-static int
+int
linux_socketpair(struct thread *td, struct linux_socketpair_args *args)
{
struct socketpair_args /* {
@@ -960,20 +879,18 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args)
int protocol;
int *rsv;
} */ bsd_args;
- int error, socket_flags;
- int sv[2];
+ int error;
bsd_args.domain = linux_to_bsd_domain(args->domain);
if (bsd_args.domain != PF_LOCAL)
return (EAFNOSUPPORT);
-
- socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK;
- if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
- return (EINVAL);
bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK;
if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX)
return (EINVAL);
-
+ error = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK,
+ &bsd_args.type);
+ if (error != 0)
+ return (error);
if (args->protocol != 0 && args->protocol != PF_UNIX)
/*
@@ -986,27 +903,10 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args)
else
bsd_args.protocol = 0;
bsd_args.rsv = (int *)PTRIN(args->rsv);
- error = kern_socketpair(td, bsd_args.domain, bsd_args.type,
- bsd_args.protocol, sv);
- if (error)
- return (error);
- error = linux_set_socket_flags(td, sv[0], socket_flags);
- if (error)
- goto out;
- error = linux_set_socket_flags(td, sv[1], socket_flags);
- if (error)
- goto out;
-
- error = copyout(sv, bsd_args.rsv, 2 * sizeof(int));
-
-out:
- if (error) {
- (void)kern_close(td, sv[0]);
- (void)kern_close(td, sv[1]);
- }
- return (error);
+ return (sys_socketpair(td, &bsd_args));
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
struct linux_send_args {
int s;
l_uintptr_t msg;
@@ -1062,8 +962,9 @@ linux_recv(struct thread *td, struct linux_recv_args *args)
bsd_args.fromlenaddr = 0;
return (sys_recvfrom(td, &bsd_args));
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
-static int
+int
linux_sendto(struct thread *td, struct linux_sendto_args *args)
{
struct msghdr msg;
@@ -1087,63 +988,58 @@ linux_sendto(struct thread *td, struct linux_sendto_args *args)
return (error);
}
-struct linux_recvfrom_args {
- int s;
- l_uintptr_t buf;
- int len;
- int flags;
- l_uintptr_t from;
- l_uintptr_t fromlen;
-};
-
-static int
+int
linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args)
{
- struct recvfrom_args /* {
- int s;
- caddr_t buf;
- size_t len;
- int flags;
- struct sockaddr * __restrict from;
- socklen_t * __restrict fromlenaddr;
- } */ bsd_args;
- size_t len;
+ struct msghdr msg;
+ struct iovec aiov;
int error;
- if ((error = copyin(PTRIN(args->fromlen), &len, sizeof(size_t))))
- return (error);
+ if (PTRIN(args->fromlen) != NULL) {
+ error = copyin(PTRIN(args->fromlen), &msg.msg_namelen,
+ sizeof(msg.msg_namelen));
+ if (error != 0)
+ return (error);
- bsd_args.s = args->s;
- bsd_args.buf = PTRIN(args->buf);
- bsd_args.len = args->len;
- bsd_args.flags = linux_to_bsd_msg_flags(args->flags);
- /* XXX: */
- bsd_args.from = (struct sockaddr * __restrict)PTRIN(args->from);
- bsd_args.fromlenaddr = PTRIN(args->fromlen);/* XXX */
-
- linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.from, len);
- error = sys_recvfrom(td, &bsd_args);
- bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.from);
-
- if (error)
+ error = linux_to_bsd_sockaddr((struct sockaddr *)PTRIN(args->from),
+ msg.msg_namelen);
+ if (error != 0)
+ return (error);
+ } else
+ msg.msg_namelen = 0;
+
+ msg.msg_name = (struct sockaddr * __restrict)PTRIN(args->from);
+ msg.msg_iov = &aiov;
+ msg.msg_iovlen = 1;
+ aiov.iov_base = PTRIN(args->buf);
+ aiov.iov_len = args->len;
+ msg.msg_control = 0;
+ msg.msg_flags = linux_to_bsd_msg_flags(args->flags);
+
+ error = kern_recvit(td, args->s, &msg, UIO_USERSPACE, NULL);
+ if (error != 0)
return (error);
- if (args->from) {
- error = linux_sa_put((struct osockaddr *)
+
+ if (PTRIN(args->from) != NULL) {
+ error = bsd_to_linux_sockaddr((struct sockaddr *)
PTRIN(args->from));
- if (error)
+ if (error != 0)
return (error);
+
+ error = linux_sa_put((struct osockaddr *)
+ PTRIN(args->from));
}
- return (0);
-}
-struct linux_sendmsg_args {
- int s;
- l_uintptr_t msg;
- int flags;
-};
+ if (PTRIN(args->fromlen) != NULL)
+ error = copyout(&msg.msg_namelen, PTRIN(args->fromlen),
+ sizeof(msg.msg_namelen));
+
+ return (error);
+}
static int
-linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
+linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
+ l_uint flags)
{
struct cmsghdr *cmsg;
struct cmsgcred cmcred;
@@ -1159,8 +1055,8 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
void *data;
int error;
- error = copyin(PTRIN(args->msg), &linux_msg, sizeof(linux_msg));
- if (error)
+ error = copyin(msghdr, &linux_msg, sizeof(linux_msg));
+ if (error != 0)
return (error);
/*
@@ -1174,7 +1070,7 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
linux_msg.msg_control = PTROUT(NULL);
error = linux_to_bsd_msghdr(&msg, &linux_msg);
- if (error)
+ if (error != 0)
return (error);
#ifdef COMPAT_LINUX32
@@ -1183,29 +1079,27 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
#else
error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
#endif
- if (error)
+ if (error != 0)
return (error);
control = NULL;
cmsg = NULL;
if ((ptr_cmsg = LINUX_CMSG_FIRSTHDR(&linux_msg)) != NULL) {
- error = kern_getsockname(td, args->s, &sa, &datalen);
- if (error)
+ error = kern_getsockname(td, s, &sa, &datalen);
+ if (error != 0)
goto bad;
sa_family = sa->sa_family;
free(sa, M_SONAME);
error = ENOBUFS;
- cmsg = malloc(CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO);
+ cmsg = malloc(CMSG_HDRSZ, M_LINUX, M_WAITOK|M_ZERO);
control = m_get(M_WAITOK, MT_CONTROL);
- if (control == NULL)
- goto bad;
do {
error = copyin(ptr_cmsg, &linux_cmsg,
sizeof(struct l_cmsghdr));
- if (error)
+ if (error != 0)
goto bad;
error = EINVAL;
@@ -1269,28 +1163,60 @@ linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
msg.msg_iov = iov;
msg.msg_flags = 0;
- error = linux_sendit(td, args->s, &msg, args->flags, control,
- UIO_USERSPACE);
+ error = linux_sendit(td, s, &msg, flags, control, UIO_USERSPACE);
bad:
+ m_freem(control);
free(iov, M_IOV);
if (cmsg)
- free(cmsg, M_TEMP);
+ free(cmsg, M_LINUX);
return (error);
}
-struct linux_recvmsg_args {
- int s;
- l_uintptr_t msg;
- int flags;
-};
+int
+linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
+{
+
+ return (linux_sendmsg_common(td, args->s, PTRIN(args->msg),
+ args->flags));
+}
+
+int
+linux_sendmmsg(struct thread *td, struct linux_sendmmsg_args *args)
+{
+ struct l_mmsghdr *msg;
+ l_uint retval;
+ int error, datagrams;
+
+ if (args->vlen > UIO_MAXIOV)
+ args->vlen = UIO_MAXIOV;
+
+ msg = PTRIN(args->msg);
+ datagrams = 0;
+ while (datagrams < args->vlen) {
+ error = linux_sendmsg_common(td, args->s, &msg->msg_hdr,
+ args->flags);
+ if (error != 0)
+ break;
+
+ retval = td->td_retval[0];
+ error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len));
+ if (error != 0)
+ break;
+ ++msg;
+ ++datagrams;
+ }
+ if (error == 0)
+ td->td_retval[0] = datagrams;
+ return (error);
+}
static int
-linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
+linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
+ l_uint flags, struct msghdr *msg)
{
struct cmsghdr *cm;
struct cmsgcred *cmcred;
- struct msghdr msg;
struct l_cmsghdr *linux_cmsg = NULL;
struct l_ucred linux_ucred;
socklen_t datalen, outlen;
@@ -1298,55 +1224,57 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
struct iovec *iov, *uiov;
struct mbuf *control = NULL;
struct mbuf **controlp;
+ struct timeval *ftmvl;
+ l_timeval ltmvl;
caddr_t outbuf;
void *data;
int error, i, fd, fds, *fdp;
- error = copyin(PTRIN(args->msg), &linux_msg, sizeof(linux_msg));
- if (error)
+ error = copyin(msghdr, &linux_msg, sizeof(linux_msg));
+ if (error != 0)
return (error);
- error = linux_to_bsd_msghdr(&msg, &linux_msg);
- if (error)
+ error = linux_to_bsd_msghdr(msg, &linux_msg);
+ if (error != 0)
return (error);
#ifdef COMPAT_LINUX32
- error = linux32_copyiniov(PTRIN(msg.msg_iov), msg.msg_iovlen,
+ error = linux32_copyiniov(PTRIN(msg->msg_iov), msg->msg_iovlen,
&iov, EMSGSIZE);
#else
- error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
+ error = copyiniov(msg->msg_iov, msg->msg_iovlen, &iov, EMSGSIZE);
#endif
- if (error)
+ if (error != 0)
return (error);
- if (msg.msg_name) {
- error = linux_to_bsd_sockaddr((struct sockaddr *)msg.msg_name,
- msg.msg_namelen);
- if (error)
+ if (msg->msg_name) {
+ error = linux_to_bsd_sockaddr((struct sockaddr *)msg->msg_name,
+ msg->msg_namelen);
+ if (error != 0)
goto bad;
}
- uiov = msg.msg_iov;
- msg.msg_iov = iov;
- controlp = (msg.msg_control != NULL) ? &control : NULL;
- error = kern_recvit(td, args->s, &msg, UIO_USERSPACE, controlp);
- msg.msg_iov = uiov;
- if (error)
+ uiov = msg->msg_iov;
+ msg->msg_iov = iov;
+ controlp = (msg->msg_control != NULL) ? &control : NULL;
+ error = kern_recvit(td, s, msg, UIO_USERSPACE, controlp);
+ msg->msg_iov = uiov;
+ if (error != 0)
goto bad;
- error = bsd_to_linux_msghdr(&msg, &linux_msg);
- if (error)
+ error = bsd_to_linux_msghdr(msg, &linux_msg);
+ if (error != 0)
goto bad;
if (linux_msg.msg_name) {
error = bsd_to_linux_sockaddr((struct sockaddr *)
PTRIN(linux_msg.msg_name));
- if (error)
+ if (error != 0)
goto bad;
}
if (linux_msg.msg_name && linux_msg.msg_namelen > 2) {
error = linux_sa_put(PTRIN(linux_msg.msg_name));
- if (error)
+ if (error != 0)
goto bad;
}
@@ -1354,12 +1282,12 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
outlen = 0;
if (control) {
- linux_cmsg = malloc(L_CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO);
+ linux_cmsg = malloc(L_CMSG_HDRSZ, M_LINUX, M_WAITOK | M_ZERO);
- msg.msg_control = mtod(control, struct cmsghdr *);
- msg.msg_controllen = control->m_len;
+ msg->msg_control = mtod(control, struct cmsghdr *);
+ msg->msg_controllen = control->m_len;
- cm = CMSG_FIRSTHDR(&msg);
+ cm = CMSG_FIRSTHDR(msg);
while (cm != NULL) {
linux_cmsg->cmsg_type =
@@ -1379,7 +1307,7 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
switch (cm->cmsg_type)
{
case SCM_RIGHTS:
- if (args->flags & LINUX_MSG_CMSG_CLOEXEC) {
+ if (flags & LINUX_MSG_CMSG_CLOEXEC) {
fds = datalen / sizeof(int);
fdp = data;
for (i = 0; i < fds; i++) {
@@ -1408,6 +1336,18 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
data = &linux_ucred;
datalen = sizeof(linux_ucred);
break;
+
+ case SCM_TIMESTAMP:
+ if (datalen != sizeof(struct timeval)) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+ ftmvl = (struct timeval *)data;
+ ltmvl.tv_sec = ftmvl->tv_sec;
+ ltmvl.tv_usec = ftmvl->tv_usec;
+ data = &ltmvl;
+ datalen = sizeof(ltmvl);
+ break;
}
if (outlen + LINUX_CMSG_LEN(datalen) >
@@ -1436,28 +1376,92 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
outbuf += LINUX_CMSG_ALIGN(datalen);
outlen += LINUX_CMSG_LEN(datalen);
- cm = CMSG_NXTHDR(&msg, cm);
+ cm = CMSG_NXTHDR(msg, cm);
}
}
out:
linux_msg.msg_controllen = outlen;
- error = copyout(&linux_msg, PTRIN(args->msg), sizeof(linux_msg));
+ error = copyout(&linux_msg, msghdr, sizeof(linux_msg));
bad:
free(iov, M_IOV);
m_freem(control);
- free(linux_cmsg, M_TEMP);
+ free(linux_cmsg, M_LINUX);
return (error);
}
-struct linux_shutdown_args {
- int s;
- int how;
-};
+int
+linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
+{
+ struct msghdr bsd_msg;
-static int
+ return (linux_recvmsg_common(td, args->s, PTRIN(args->msg),
+ args->flags, &bsd_msg));
+}
+
+int
+linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args)
+{
+ struct l_mmsghdr *msg;
+ struct msghdr bsd_msg;
+ struct l_timespec lts;
+ struct timespec ts, tts;
+ l_uint retval;
+ int error, datagrams;
+
+ if (args->timeout) {
+ error = copyin(args->timeout, &lts, sizeof(struct l_timespec));
+ if (error != 0)
+ return (error);
+ error = linux_to_native_timespec(&ts, &lts);
+ if (error != 0)
+ return (error);
+ getnanotime(&tts);
+ timespecadd(&tts, &ts);
+ }
+
+ msg = PTRIN(args->msg);
+ datagrams = 0;
+ while (datagrams < args->vlen) {
+ error = linux_recvmsg_common(td, args->s, &msg->msg_hdr,
+ args->flags & ~LINUX_MSG_WAITFORONE, &bsd_msg);
+ if (error != 0)
+ break;
+
+ retval = td->td_retval[0];
+ error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len));
+ if (error != 0)
+ break;
+ ++msg;
+ ++datagrams;
+
+ /*
+ * MSG_WAITFORONE turns on MSG_DONTWAIT after one packet.
+ */
+ if (args->flags & LINUX_MSG_WAITFORONE)
+ args->flags |= LINUX_MSG_DONTWAIT;
+
+ /*
+ * See BUGS section of recvmmsg(2).
+ */
+ if (args->timeout) {
+ getnanotime(&ts);
+ timespecsub(&ts, &tts);
+ if (!timespecisset(&ts) || ts.tv_sec > 0)
+ break;
+ }
+ /* Out of band data, return right away. */
+ if (bsd_msg.msg_flags & MSG_OOB)
+ break;
+ }
+ if (error == 0)
+ td->td_retval[0] = datagrams;
+ return (error);
+}
+
+int
linux_shutdown(struct thread *td, struct linux_shutdown_args *args)
{
struct shutdown_args /* {
@@ -1470,15 +1474,7 @@ linux_shutdown(struct thread *td, struct linux_shutdown_args *args)
return (sys_shutdown(td, &bsd_args));
}
-struct linux_setsockopt_args {
- int s;
- int level;
- int optname;
- l_uintptr_t optval;
- int optlen;
-};
-
-static int
+int
linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
{
struct setsockopt_args /* {
@@ -1543,15 +1539,7 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
return (error);
}
-struct linux_getsockopt_args {
- int s;
- int level;
- int optname;
- l_uintptr_t optval;
- l_uintptr_t optlen;
-};
-
-static int
+int
linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
{
struct getsockopt_args /* {
@@ -1635,6 +1623,8 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
return (error);
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+
/* Argument list sizes for linux_socketcall */
#define LINUX_AL(x) ((x) * sizeof(l_ulong))
@@ -1649,7 +1639,8 @@ static const unsigned char lxs_args[] = {
LINUX_AL(6) /* recvfrom */, LINUX_AL(2) /* shutdown */,
LINUX_AL(5) /* setsockopt */, LINUX_AL(5) /* getsockopt */,
LINUX_AL(3) /* sendmsg */, LINUX_AL(3) /* recvmsg */,
- LINUX_AL(4) /* accept4 */
+ LINUX_AL(4) /* accept4 */, LINUX_AL(5) /* recvmmsg */,
+ LINUX_AL(4) /* sendmmsg */
};
#define LINUX_AL_SIZE sizeof(lxs_args) / sizeof(lxs_args[0]) - 1
@@ -1705,8 +1696,13 @@ linux_socketcall(struct thread *td, struct linux_socketcall_args *args)
return (linux_recvmsg(td, arg));
case LINUX_ACCEPT4:
return (linux_accept4(td, arg));
+ case LINUX_RECVMMSG:
+ return (linux_recvmmsg(td, arg));
+ case LINUX_SENDMMSG:
+ return (linux_sendmmsg(td, arg));
}
uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what);
return (ENOSYS);
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h
index e6efadb684ab..b32a9694dff2 100644
--- a/sys/compat/linux/linux_socket.h
+++ b/sys/compat/linux/linux_socket.h
@@ -48,12 +48,36 @@
#define LINUX_MSG_RST 0x1000
#define LINUX_MSG_ERRQUEUE 0x2000
#define LINUX_MSG_NOSIGNAL 0x4000
+#define LINUX_MSG_WAITFORONE 0x10000
#define LINUX_MSG_CMSG_CLOEXEC 0x40000000
/* Socket-level control message types */
#define LINUX_SCM_RIGHTS 0x01
-#define LINUX_SCM_CREDENTIALS 0x02
+#define LINUX_SCM_CREDENTIALS 0x02
+#define LINUX_SCM_TIMESTAMP 0x1D
+
+struct l_msghdr {
+ l_uintptr_t msg_name;
+ l_int msg_namelen;
+ l_uintptr_t msg_iov;
+ l_size_t msg_iovlen;
+ l_uintptr_t msg_control;
+ l_size_t msg_controllen;
+ l_uint msg_flags;
+};
+
+struct l_mmsghdr {
+ struct l_msghdr msg_hdr;
+ l_uint msg_len;
+
+};
+
+struct l_cmsghdr {
+ l_size_t cmsg_len;
+ l_int cmsg_level;
+ l_int cmsg_type;
+};
/* Ancilliary data object information macros */
@@ -116,6 +140,133 @@ struct l_ucred {
uint32_t gid;
};
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+
+struct linux_sendto_args {
+ int s;
+ l_uintptr_t msg;
+ int len;
+ int flags;
+ l_uintptr_t to;
+ int tolen;
+};
+
+struct linux_socket_args {
+ int domain;
+ int type;
+ int protocol;
+};
+
+struct linux_bind_args {
+ int s;
+ l_uintptr_t name;
+ int namelen;
+};
+
+struct linux_connect_args {
+ int s;
+ l_uintptr_t name;
+ int namelen;
+};
+
+struct linux_listen_args {
+ int s;
+ int backlog;
+};
+
+struct linux_accept_args {
+ int s;
+ l_uintptr_t addr;
+ l_uintptr_t namelen;
+};
+
+struct linux_accept4_args {
+ int s;
+ l_uintptr_t addr;
+ l_uintptr_t namelen;
+ int flags;
+};
+
+struct linux_getsockname_args {
+ int s;
+ l_uintptr_t addr;
+ l_uintptr_t namelen;
+};
+
+struct linux_getpeername_args {
+ int s;
+ l_uintptr_t addr;
+ l_uintptr_t namelen;
+};
+
+struct linux_socketpair_args {
+ int domain;
+ int type;
+ int protocol;
+ l_uintptr_t rsv;
+};
+
+struct linux_recvfrom_args {
+ int s;
+ l_uintptr_t buf;
+ int len;
+ int flags;
+ l_uintptr_t from;
+ l_uintptr_t fromlen;
+};
+
+struct linux_sendmsg_args {
+ int s;
+ l_uintptr_t msg;
+ int flags;
+};
+
+struct linux_recvmsg_args {
+ int s;
+ l_uintptr_t msg;
+ int flags;
+};
+
+struct linux_shutdown_args {
+ int s;
+ int how;
+};
+
+struct linux_setsockopt_args {
+ int s;
+ int level;
+ int optname;
+ l_uintptr_t optval;
+ int optlen;
+};
+
+struct linux_getsockopt_args {
+ int s;
+ int level;
+ int optname;
+ l_uintptr_t optval;
+ l_uintptr_t optlen;
+};
+
+int linux_socket(struct thread *td, struct linux_socket_args *args);
+int linux_bind(struct thread *td, struct linux_bind_args *args);
+int linux_connect(struct thread *, struct linux_connect_args *);
+int linux_listen(struct thread *td, struct linux_listen_args *args);
+int linux_accept(struct thread *td, struct linux_accept_args *args);
+int linux_accept4(struct thread *td, struct linux_accept4_args *args);
+int linux_getsockname(struct thread *td, struct linux_getsockname_args *args);
+int linux_getpeername(struct thread *td, struct linux_getpeername_args *args);
+int linux_socketpair(struct thread *td, struct linux_socketpair_args *args);
+int linux_sendto(struct thread *td, struct linux_sendto_args *args);
+int linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args);
+int linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args);
+int linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args);
+int linux_shutdown(struct thread *td, struct linux_shutdown_args *args);
+int linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args);
+int linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args);
+
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
/* Operations for socketcall */
#define LINUX_SOCKET 1
@@ -136,6 +287,8 @@ struct l_ucred {
#define LINUX_SENDMSG 16
#define LINUX_RECVMSG 17
#define LINUX_ACCEPT4 18
+#define LINUX_RECVMMSG 19
+#define LINUX_SENDMMSG 20
/* Socket options */
#define LINUX_IP_TOS 1
diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c
index b6dd86dd6ad4..05d335adf468 100644
--- a/sys/compat/linux/linux_stats.c
+++ b/sys/compat/linux/linux_stats.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include "opt_compat.h"
#include <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/dirent.h>
#include <sys/file.h>
#include <sys/filedesc.h>
@@ -58,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_util.h>
#include <compat/linux/linux_file.h>
-#define LINUX_SHMFS_MAGIC 0x01021994
static void
translate_vnhook_major_minor(struct vnode *vp, struct stat *sb)
@@ -251,6 +251,7 @@ linux_newfstat(struct thread *td, struct linux_newfstat_args *args)
return (error);
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
static int
stat_copyout(struct stat *buf, void *ubuf)
{
@@ -325,19 +326,19 @@ linux_lstat(struct thread *td, struct linux_lstat_args *args)
LFREEPATH(path);
return(stat_copyout(&buf, args->up));
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
-/* XXX - All fields of type l_int are defined as l_long on i386 */
struct l_statfs {
- l_int f_type;
- l_int f_bsize;
- l_int f_blocks;
- l_int f_bfree;
- l_int f_bavail;
- l_int f_files;
- l_int f_ffree;
+ l_long f_type;
+ l_long f_bsize;
+ l_long f_blocks;
+ l_long f_bfree;
+ l_long f_bavail;
+ l_long f_files;
+ l_long f_ffree;
l_fsid_t f_fsid;
- l_int f_namelen;
- l_int f_spare[6];
+ l_long f_namelen;
+ l_long f_spare[6];
};
#define LINUX_CODA_SUPER_MAGIC 0x73757245L
@@ -351,6 +352,7 @@ struct l_statfs {
#define LINUX_PROC_SUPER_MAGIC 0x9fa0L
#define LINUX_UFS_SUPER_MAGIC 0x00011954L /* XXX - UFS_MAGIC in Linux */
#define LINUX_DEVFS_SUPER_MAGIC 0x1373L
+#define LINUX_SHMFS_MAGIC 0x01021994
static long
bsd_to_linux_ftype(const char *fstypename)
@@ -368,6 +370,7 @@ bsd_to_linux_ftype(const char *fstypename)
{"hpfs", LINUX_HPFS_SUPER_MAGIC},
{"coda", LINUX_CODA_SUPER_MAGIC},
{"devfs", LINUX_DEVFS_SUPER_MAGIC},
+ {"tmpfs", LINUX_SHMFS_MAGIC},
{NULL, 0L}};
for (i = 0; b2l_tbl[i].bsd_name != NULL; i++)
@@ -399,7 +402,7 @@ linux_statfs(struct thread *td, struct linux_statfs_args *args)
struct l_statfs linux_statfs;
struct statfs bsd_statfs;
char *path;
- int error, dev_shm;
+ int error;
LCONVPATHEXIST(td, args->path, &path);
@@ -407,20 +410,15 @@ linux_statfs(struct thread *td, struct linux_statfs_args *args)
if (ldebug(statfs))
printf(ARGS(statfs, "%s, *"), path);
#endif
- dev_shm = 0;
error = kern_statfs(td, path, UIO_SYSSPACE, &bsd_statfs);
- if (strncmp(path, "/dev/shm", sizeof("/dev/shm") - 1) == 0)
- dev_shm = (path[8] == '\0'
- || (path[8] == '/' && path[9] == '\0'));
LFREEPATH(path);
if (error)
return (error);
bsd_to_linux_statfs(&bsd_statfs, &linux_statfs);
- if (dev_shm)
- linux_statfs.f_type = LINUX_SHMFS_MAGIC;
return copyout(&linux_statfs, args->buf, sizeof(linux_statfs));
}
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
static void
bsd_to_linux_statfs64(struct statfs *bsd_statfs, struct l_statfs64 *linux_statfs)
{
@@ -461,6 +459,7 @@ linux_statfs64(struct thread *td, struct linux_statfs64_args *args)
bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs);
return copyout(&linux_statfs, args->buf, sizeof(linux_statfs));
}
+#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args)
@@ -493,7 +492,7 @@ linux_ustat(struct thread *td, struct linux_ustat_args *args)
{
#ifdef DEBUG
if (ldebug(ustat))
- printf(ARGS(ustat, "%d, *"), args->dev);
+ printf(ARGS(ustat, "%ju, *"), (uintmax_t)args->dev);
#endif
return (EOPNOTSUPP);
@@ -624,4 +623,74 @@ linux_fstatat64(struct thread *td, struct linux_fstatat64_args *args)
return (error);
}
+#else /* __amd64__ && !COMPAT_LINUX32 */
+
+int
+linux_newfstatat(struct thread *td, struct linux_newfstatat_args *args)
+{
+ char *path;
+ int error, dfd, flag;
+ struct stat buf;
+
+ if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW)
+ return (EINVAL);
+ flag = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) ?
+ AT_SYMLINK_NOFOLLOW : 0;
+
+ dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
+ LCONVPATHEXIST_AT(td, args->pathname, &path, dfd);
+
+#ifdef DEBUG
+ if (ldebug(newfstatat))
+ printf(ARGS(newfstatat, "%i, %s, %i"), args->dfd, path, args->flag);
+#endif
+
+ error = linux_kern_statat(td, flag, dfd, path, UIO_SYSSPACE, &buf);
+ if (error == 0)
+ error = newstat_copyout(&buf, args->statbuf);
+ LFREEPATH(path);
+
+ return (error);
+}
+
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
+
+int
+linux_syncfs(struct thread *td, struct linux_syncfs_args *args)
+{
+ cap_rights_t rights;
+ struct mount *mp;
+ struct vnode *vp;
+ int error, save;
+
+ error = fgetvp(td, args->fd, cap_rights_init(&rights, CAP_FSYNC), &vp);
+ if (error != 0)
+ /*
+ * Linux syncfs() returns only EBADF, however fgetvp()
+ * can return EINVAL in case of file descriptor does
+ * not represent a vnode. XXX.
+ */
+ return (error);
+
+ mp = vp->v_mount;
+ mtx_lock(&mountlist_mtx);
+ error = vfs_busy(mp, MBF_MNTLSTLOCK);
+ if (error != 0) {
+ /* See comment above. */
+ mtx_unlock(&mountlist_mtx);
+ goto out;
+ }
+ if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
+ vn_start_write(NULL, &mp, V_NOWAIT) == 0) {
+ save = curthread_pflags_set(TDP_SYNCIO);
+ vfs_msync(mp, MNT_NOWAIT);
+ VFS_SYNC(mp, MNT_NOWAIT);
+ curthread_pflags_restore(save);
+ vn_finished_write(mp);
+ }
+ vfs_unbusy(mp);
+
+ out:
+ vrele(vp);
+ return (error);
+}
diff --git a/sys/compat/linux/linux_sysctl.c b/sys/compat/linux/linux_sysctl.c
index 7d263df8616b..44fe41dd3f9e 100644
--- a/sys/compat/linux/linux_sysctl.c
+++ b/sys/compat/linux/linux_sysctl.c
@@ -140,12 +140,12 @@ linux_sysctl(struct thread *td, struct linux_sysctl_args *args)
return (ENOTDIR);
}
- mib = malloc(la.nlen * sizeof(l_int), M_TEMP, M_WAITOK);
+ mib = malloc(la.nlen * sizeof(l_int), M_LINUX, M_WAITOK);
error = copyin(PTRIN(la.name), mib, la.nlen * sizeof(l_int));
if (error) {
LIN_SDT_PROBE1(sysctl, linux_sysctl, copyin_error, error);
LIN_SDT_PROBE1(sysctl, linux_sysctl, return, error);
- free(mib, M_TEMP);
+ free(mib, M_LINUX);
return (error);
}
@@ -157,7 +157,7 @@ linux_sysctl(struct thread *td, struct linux_sysctl_args *args)
switch (mib[1]) {
case LINUX_KERN_VERSION:
error = handle_string(&la, version);
- free(mib, M_TEMP);
+ free(mib, M_LINUX);
LIN_SDT_PROBE1(sysctl, linux_sysctl, return, error);
return (error);
default:
@@ -186,7 +186,7 @@ linux_sysctl(struct thread *td, struct linux_sysctl_args *args)
sbuf_delete(sb);
}
- free(mib, M_TEMP);
+ free(mib, M_LINUX);
LIN_SDT_PROBE1(sysctl, linux_sysctl, return, ENOTDIR);
return (ENOTDIR);
diff --git a/sys/compat/linux/linux_time.c b/sys/compat/linux/linux_time.c
index be6e169b26c9..2d293306ee61 100644
--- a/sys/compat/linux/linux_time.c
+++ b/sys/compat/linux/linux_time.c
@@ -39,8 +39,11 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/ucred.h>
#include <sys/mount.h>
+#include <sys/mutex.h>
+#include <sys/resourcevar.h>
#include <sys/sdt.h>
#include <sys/signal.h>
#include <sys/stdint.h>
@@ -59,7 +62,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp
#endif
#include <compat/linux/linux_dtrace.h>
-#include <compat/linux/linux_misc.h>
+#include <compat/linux/linux_timer.h>
/* DTrace init */
LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
@@ -102,27 +105,20 @@ LIN_SDT_PROBE_DEFINE1(time, linux_clock_getres, return, "int");
LIN_SDT_PROBE_DEFINE2(time, linux_nanosleep, entry, "const struct l_timespec *",
"struct l_timespec *");
LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, conversion_error, "int");
-LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, nanosleep_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyout_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, copyin_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_nanosleep, return, "int");
LIN_SDT_PROBE_DEFINE4(time, linux_clock_nanosleep, entry, "clockid_t", "int",
"struct l_timespec *", "struct l_timespec *");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, conversion_error, "int");
-LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, nanosleep_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyout_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, copyin_error, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_flags, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, unsupported_clockid, "int");
LIN_SDT_PROBE_DEFINE1(time, linux_clock_nanosleep, return, "int");
-static void native_to_linux_timespec(struct l_timespec *,
- struct timespec *);
-static int linux_to_native_timespec(struct timespec *,
- struct l_timespec *);
-static int linux_to_native_clockid(clockid_t *, clockid_t);
-static void
+void
native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
{
@@ -134,7 +130,7 @@ native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp)
LIN_SDT_PROBE0(time, native_to_linux_timespec, return);
}
-static int
+int
linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
{
@@ -151,12 +147,26 @@ linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp)
return (0);
}
-static int
+int
linux_to_native_clockid(clockid_t *n, clockid_t l)
{
LIN_SDT_PROBE2(time, linux_to_native_clockid, entry, n, l);
+ if (l < 0) {
+ /* cpu-clock */
+ if ((l & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD)
+ return (EINVAL);
+ if (LINUX_CPUCLOCK_WHICH(l) >= LINUX_CPUCLOCK_MAX)
+ return (EINVAL);
+
+ if (LINUX_CPUCLOCK_PERTHREAD(l))
+ *n = CLOCK_THREAD_CPUTIME_ID;
+ else
+ *n = CLOCK_PROCESS_CPUTIME_ID;
+ return (0);
+ }
+
switch (l) {
case LINUX_CLOCK_REALTIME:
*n = CLOCK_REALTIME;
@@ -164,21 +174,27 @@ linux_to_native_clockid(clockid_t *n, clockid_t l)
case LINUX_CLOCK_MONOTONIC:
*n = CLOCK_MONOTONIC;
break;
- case LINUX_CLOCK_PROCESS_CPUTIME_ID:
- case LINUX_CLOCK_THREAD_CPUTIME_ID:
- case LINUX_CLOCK_REALTIME_HR:
- case LINUX_CLOCK_MONOTONIC_HR:
+ case LINUX_CLOCK_REALTIME_COARSE:
+ *n = CLOCK_REALTIME_FAST;
+ break;
+ case LINUX_CLOCK_MONOTONIC_COARSE:
+ *n = CLOCK_MONOTONIC_FAST;
+ break;
+ case LINUX_CLOCK_MONOTONIC_RAW:
+ case LINUX_CLOCK_BOOTTIME:
+ case LINUX_CLOCK_REALTIME_ALARM:
+ case LINUX_CLOCK_BOOTTIME_ALARM:
+ case LINUX_CLOCK_SGI_CYCLE:
+ case LINUX_CLOCK_TAI:
LIN_SDT_PROBE1(time, linux_to_native_clockid,
unsupported_clockid, l);
LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
return (EINVAL);
- break;
default:
LIN_SDT_PROBE1(time, linux_to_native_clockid,
unknown_clockid, l);
LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
return (EINVAL);
- break;
}
LIN_SDT_PROBE1(time, linux_to_native_clockid, return, 0);
@@ -189,9 +205,14 @@ int
linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
{
struct l_timespec lts;
- int error;
- clockid_t nwhich = 0; /* XXX: GCC */
struct timespec tp;
+ struct rusage ru;
+ struct thread *targettd;
+ struct proc *p;
+ int error, clockwhich;
+ clockid_t nwhich = 0; /* XXX: GCC */
+ pid_t pid;
+ lwpid_t tid;
LIN_SDT_PROBE2(time, linux_clock_gettime, entry, args->which, args->tp);
@@ -202,7 +223,100 @@ linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
return (error);
}
- error = kern_clock_gettime(td, nwhich, &tp);
+
+ switch (nwhich) {
+ case CLOCK_PROCESS_CPUTIME_ID:
+ clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
+ pid = LINUX_CPUCLOCK_ID(args->which);
+ if (pid == 0) {
+ p = td->td_proc;
+ PROC_LOCK(p);
+ } else {
+ error = pget(pid, PGET_CANSEE, &p);
+ if (error != 0)
+ return (EINVAL);
+ }
+ switch (clockwhich) {
+ case LINUX_CPUCLOCK_PROF:
+ PROC_STATLOCK(p);
+ calcru(p, &ru.ru_utime, &ru.ru_stime);
+ PROC_STATUNLOCK(p);
+ PROC_UNLOCK(p);
+ timevaladd(&ru.ru_utime, &ru.ru_stime);
+ TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
+ break;
+ case LINUX_CPUCLOCK_VIRT:
+ PROC_STATLOCK(p);
+ calcru(p, &ru.ru_utime, &ru.ru_stime);
+ PROC_STATUNLOCK(p);
+ PROC_UNLOCK(p);
+ TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
+ break;
+ case LINUX_CPUCLOCK_SCHED:
+ PROC_UNLOCK(p);
+ error = kern_clock_getcpuclockid2(td, pid,
+ CPUCLOCK_WHICH_PID, &nwhich);
+ if (error != 0)
+ return (EINVAL);
+ error = kern_clock_gettime(td, nwhich, &tp);
+ break;
+ default:
+ PROC_UNLOCK(p);
+ return (EINVAL);
+ }
+
+ break;
+
+ case CLOCK_THREAD_CPUTIME_ID:
+ clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
+ p = td->td_proc;
+ tid = LINUX_CPUCLOCK_ID(args->which);
+ if (tid == 0) {
+ targettd = td;
+ PROC_LOCK(p);
+ } else {
+ targettd = tdfind(tid, p->p_pid);
+ if (targettd == NULL)
+ return (EINVAL);
+ }
+ switch (clockwhich) {
+ case LINUX_CPUCLOCK_PROF:
+ PROC_STATLOCK(p);
+ thread_lock(targettd);
+ rufetchtd(targettd, &ru);
+ thread_unlock(targettd);
+ PROC_STATUNLOCK(p);
+ PROC_UNLOCK(p);
+ timevaladd(&ru.ru_utime, &ru.ru_stime);
+ TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
+ break;
+ case LINUX_CPUCLOCK_VIRT:
+ PROC_STATLOCK(p);
+ thread_lock(targettd);
+ rufetchtd(targettd, &ru);
+ thread_unlock(targettd);
+ PROC_STATUNLOCK(p);
+ PROC_UNLOCK(p);
+ TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
+ break;
+ case LINUX_CPUCLOCK_SCHED:
+ error = kern_clock_getcpuclockid2(td, tid,
+ CPUCLOCK_WHICH_TID, &nwhich);
+ PROC_UNLOCK(p);
+ if (error != 0)
+ return (EINVAL);
+ error = kern_clock_gettime(td, nwhich, &tp);
+ break;
+ default:
+ PROC_UNLOCK(p);
+ return (EINVAL);
+ }
+ break;
+
+ default:
+ error = kern_clock_gettime(td, nwhich, &tp);
+ break;
+ }
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error);
LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
@@ -260,19 +374,16 @@ linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args)
int
linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args)
{
+ struct proc *p;
struct timespec ts;
struct l_timespec lts;
- int error;
+ int error, clockwhich;
clockid_t nwhich = 0; /* XXX: GCC */
+ pid_t pid;
+ lwpid_t tid;
LIN_SDT_PROBE2(time, linux_clock_getres, entry, args->which, args->tp);
- if (args->tp == NULL) {
- LIN_SDT_PROBE0(time, linux_clock_getres, nullcall);
- LIN_SDT_PROBE1(time, linux_clock_getres, return, 0);
- return (0);
- }
-
error = linux_to_native_clockid(&nwhich, args->which);
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_getres, conversion_error,
@@ -280,6 +391,59 @@ linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args)
LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
return (error);
}
+
+ /*
+ * Check user supplied clock id in case of per-process
+ * or thread-specific cpu-time clock.
+ */
+ switch (nwhich) {
+ case CLOCK_THREAD_CPUTIME_ID:
+ tid = LINUX_CPUCLOCK_ID(args->which);
+ if (tid != 0) {
+ p = td->td_proc;
+ if (tdfind(tid, p->p_pid) == NULL)
+ return (ESRCH);
+ PROC_UNLOCK(p);
+ }
+ break;
+ case CLOCK_PROCESS_CPUTIME_ID:
+ pid = LINUX_CPUCLOCK_ID(args->which);
+ if (pid != 0) {
+ error = pget(pid, PGET_CANSEE, &p);
+ if (error != 0)
+ return (EINVAL);
+ PROC_UNLOCK(p);
+ }
+ break;
+ }
+
+ if (args->tp == NULL) {
+ LIN_SDT_PROBE0(time, linux_clock_getres, nullcall);
+ LIN_SDT_PROBE1(time, linux_clock_getres, return, 0);
+ return (0);
+ }
+
+ switch (nwhich) {
+ case CLOCK_THREAD_CPUTIME_ID:
+ case CLOCK_PROCESS_CPUTIME_ID:
+ clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
+ switch (clockwhich) {
+ case LINUX_CPUCLOCK_PROF:
+ nwhich = CLOCK_PROF;
+ break;
+ case LINUX_CPUCLOCK_VIRT:
+ nwhich = CLOCK_VIRTUAL;
+ break;
+ case LINUX_CPUCLOCK_SCHED:
+ break;
+ default:
+ return (EINVAL);
+ }
+ break;
+
+ default:
+ break;
+ }
error = kern_clock_getres(td, nwhich, &ts);
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_getres, getres_error, error);
@@ -302,7 +466,7 @@ linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args)
struct timespec *rmtp;
struct l_timespec lrqts, lrmts;
struct timespec rqts, rmts;
- int error;
+ int error, error2;
LIN_SDT_PROBE2(time, linux_nanosleep, entry, args->rqtp, args->rmtp);
@@ -314,9 +478,9 @@ linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args)
}
if (args->rmtp != NULL)
- rmtp = &rmts;
+ rmtp = &rmts;
else
- rmtp = NULL;
+ rmtp = NULL;
error = linux_to_native_timespec(&rqts, &lrqts);
if (error != 0) {
@@ -325,25 +489,19 @@ linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args)
return (error);
}
error = kern_nanosleep(td, &rqts, rmtp);
- if (error != 0) {
- LIN_SDT_PROBE1(time, linux_nanosleep, nanosleep_error, error);
- LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
- return (error);
- }
-
if (args->rmtp != NULL) {
- native_to_linux_timespec(&lrmts, rmtp);
- error = copyout(&lrmts, args->rmtp, sizeof(lrmts));
- if (error != 0) {
+ native_to_linux_timespec(&lrmts, rmtp);
+ error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts));
+ if (error2 != 0) {
LIN_SDT_PROBE1(time, linux_nanosleep, copyout_error,
- error);
- LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
- return (error);
+ error2);
+ LIN_SDT_PROBE1(time, linux_nanosleep, return, error2);
+ return (error2);
}
}
- LIN_SDT_PROBE1(time, linux_nanosleep, return, 0);
- return (0);
+ LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
+ return (error);
}
int
@@ -352,7 +510,7 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args
struct timespec *rmtp;
struct l_timespec lrqts, lrmts;
struct timespec rqts, rmts;
- int error;
+ int error, error2;
LIN_SDT_PROBE4(time, linux_clock_nanosleep, entry, args->which,
args->flags, args->rqtp, args->rmtp);
@@ -372,7 +530,7 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args
return (EINVAL);
}
- error = copyin(args->rqtp, &lrqts, sizeof lrqts);
+ error = copyin(args->rqtp, &lrqts, sizeof(lrqts));
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_nanosleep, copyin_error,
error);
@@ -381,9 +539,9 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args
}
if (args->rmtp != NULL)
- rmtp = &rmts;
+ rmtp = &rmts;
else
- rmtp = NULL;
+ rmtp = NULL;
error = linux_to_native_timespec(&rqts, &lrqts);
if (error != 0) {
@@ -393,24 +551,19 @@ linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args
return (error);
}
error = kern_nanosleep(td, &rqts, rmtp);
- if (error != 0) {
- LIN_SDT_PROBE1(time, linux_clock_nanosleep, nanosleep_error,
- error);
- LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
- return (error);
- }
-
if (args->rmtp != NULL) {
+ /* XXX. Not for TIMER_ABSTIME */
native_to_linux_timespec(&lrmts, rmtp);
- error = copyout(&lrmts, args->rmtp, sizeof lrmts );
- if (error != 0) {
+ error2 = copyout(&lrmts, args->rmtp, sizeof(lrmts));
+ if (error2 != 0) {
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep,
+ copyout_error, error2);
LIN_SDT_PROBE1(time, linux_clock_nanosleep,
- copyout_error, error);
- LIN_SDT_PROBE1(time, linux_nanosleep, return, error);
- return (error);
+ return, error2);
+ return (error2);
}
}
- LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, 0);
- return (0);
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
+ return (error);
}
diff --git a/sys/compat/linux/linux_timer.c b/sys/compat/linux/linux_timer.c
index 92dae4c67280..7dbddbe30adb 100644
--- a/sys/compat/linux/linux_timer.c
+++ b/sys/compat/linux/linux_timer.c
@@ -49,23 +49,6 @@ __FBSDID("$FreeBSD$");
#endif
#include <compat/linux/linux_timer.h>
-static int
-linux_convert_l_clockid(clockid_t *clock_id)
-{
-
- switch (*clock_id) {
- case LINUX_CLOCK_REALTIME:
- *clock_id = CLOCK_REALTIME;
- break;
- case LINUX_CLOCK_MONOTONIC:
- *clock_id = CLOCK_MONOTONIC;
- break;
- default:
- return (EINVAL);
- }
-
- return (0);
-}
static int
linux_convert_l_sigevent(struct l_sigevent *l_sig, struct sigevent *sig)
@@ -75,7 +58,7 @@ linux_convert_l_sigevent(struct l_sigevent *l_sig, struct sigevent *sig)
switch (l_sig->sigev_notify) {
case L_SIGEV_SIGNAL:
sig->sigev_notify = SIGEV_SIGNAL;
- CP(*l_sig, *sig, sigev_signo);
+ sig->sigev_signo = linux_to_bsd_signal(l_sig->sigev_signo);
PTRIN_CP(*l_sig, *sig, sigev_value.sival_ptr);
break;
case L_SIGEV_NONE:
@@ -92,7 +75,7 @@ linux_convert_l_sigevent(struct l_sigevent *l_sig, struct sigevent *sig)
case L_SIGEV_THREAD_ID:
sig->sigev_notify = SIGEV_THREAD_ID;
CP2(*l_sig, *sig, _l_sigev_un._tid, sigev_notify_thread_id);
- CP(*l_sig, *sig, sigev_signo);
+ sig->sigev_signo = linux_to_bsd_signal(l_sig->sigev_signo);
PTRIN_CP(*l_sig, *sig, sigev_value.sival_ptr);
break;
default:
@@ -106,6 +89,7 @@ linux_timer_create(struct thread *td, struct linux_timer_create_args *uap)
{
struct l_sigevent l_ev;
struct sigevent ev, *evp;
+ clockid_t nwhich;
int error, id;
if (uap->evp == NULL) {
@@ -119,10 +103,10 @@ linux_timer_create(struct thread *td, struct linux_timer_create_args *uap)
return (error);
evp = &ev;
}
- error = linux_convert_l_clockid(&uap->clock_id);
+ error = linux_to_native_clockid(&nwhich, uap->clock_id);
if (error != 0)
return (error);
- error = kern_ktimer_create(td, uap->clock_id, evp, &id, -1);
+ error = kern_ktimer_create(td, nwhich, evp, &id, -1);
if (error == 0) {
error = copyout(&id, uap->timerid, sizeof(int));
if (error != 0)
@@ -179,4 +163,3 @@ linux_timer_delete(struct thread *td, struct linux_timer_delete_args *uap)
return (kern_ktimer_delete(td, uap->timerid));
}
-
diff --git a/sys/compat/linux/linux_timer.h b/sys/compat/linux/linux_timer.h
index 4f64ee5fe9cb..c79c08dc39fc 100644
--- a/sys/compat/linux/linux_timer.h
+++ b/sys/compat/linux/linux_timer.h
@@ -56,6 +56,23 @@
#define LINUX_CLOCK_SGI_CYCLE 10
#define LINUX_CLOCK_TAI 11
+#define LINUX_CPUCLOCK_PERTHREAD_MASK 4
+#define LINUX_CPUCLOCK_MASK 3
+#define LINUX_CPUCLOCK_WHICH(clock) \
+ ((clock) & (clockid_t) LINUX_CPUCLOCK_MASK)
+#define LINUX_CPUCLOCK_PROF 0
+#define LINUX_CPUCLOCK_VIRT 1
+#define LINUX_CPUCLOCK_SCHED 2
+#define LINUX_CPUCLOCK_MAX 3
+#define LINUX_CLOCKFD LINUX_CPUCLOCK_MAX
+#define LINUX_CLOCKFD_MASK \
+ (LINUX_CPUCLOCK_PERTHREAD_MASK|LINUX_CPUCLOCK_MASK)
+
+#define LINUX_CPUCLOCK_ID(clock) ((pid_t) ~((clock) >> 3))
+#define LINUX_CPUCLOCK_PERTHREAD(clock) \
+ (((clock) & (clockid_t) LINUX_CPUCLOCK_PERTHREAD_MASK) != 0)
+
+
#define L_SIGEV_SIGNAL 0
#define L_SIGEV_NONE 1
#define L_SIGEV_THREAD 2
@@ -94,4 +111,10 @@ struct l_itimerspec {
struct l_timespec it_value;
};
+void native_to_linux_timespec(struct l_timespec *,
+ struct timespec *);
+int linux_to_native_timespec(struct timespec *,
+ struct l_timespec *);
+int linux_to_native_clockid(clockid_t *, clockid_t);
+
#endif /* _LINUX_TIMER_H */
diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c
index 8c7c7606920a..8aa728cf73e6 100644
--- a/sys/compat/linux/linux_uid16.c
+++ b/sys/compat/linux/linux_uid16.c
@@ -171,12 +171,12 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
LIN_SDT_PROBE1(uid16, linux_setgroups16, return, EINVAL);
return (EINVAL);
}
- linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
+ linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK);
error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t));
if (error) {
LIN_SDT_PROBE1(uid16, linux_setgroups16, copyin_error, error);
LIN_SDT_PROBE1(uid16, linux_setgroups16, return, error);
- free(linux_gidset, M_TEMP);
+ free(linux_gidset, M_LINUX);
return (error);
}
newcred = crget();
@@ -218,7 +218,7 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
crfree(oldcred);
error = 0;
out:
- free(linux_gidset, M_TEMP);
+ free(linux_gidset, M_LINUX);
LIN_SDT_PROBE1(uid16, linux_setgroups16, return, error);
return (error);
@@ -259,14 +259,14 @@ linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
ngrp = 0;
linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
- M_TEMP, M_WAITOK);
+ M_LINUX, M_WAITOK);
while (ngrp < bsd_gidsetsz) {
linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
ngrp++;
}
error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
- free(linux_gidset, M_TEMP);
+ free(linux_gidset, M_LINUX);
if (error) {
LIN_SDT_PROBE1(uid16, linux_getgroups16, copyout_error, error);
LIN_SDT_PROBE1(uid16, linux_getgroups16, return, error);
diff --git a/sys/compat/linux/linux_util.c b/sys/compat/linux/linux_util.c
index be52459c4b84..466c588157c5 100644
--- a/sys/compat/linux/linux_util.c
+++ b/sys/compat/linux/linux_util.c
@@ -52,48 +52,14 @@ __FBSDID("$FreeBSD$");
#include <machine/stdarg.h>
#include <compat/linux/linux_util.h>
-#ifdef COMPAT_LINUX32
-#include <machine/../linux32/linux.h>
-#else
-#include <machine/../linux/linux.h>
-#endif
-#include <compat/linux/linux_dtrace.h>
+MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
+MALLOC_DEFINE(M_EPOLL, "lepoll", "Linux events structures");
+MALLOC_DEFINE(M_FUTEX, "futex", "Linux futexes");
+MALLOC_DEFINE(M_FUTEX_WP, "futex wp", "Linux futex waiting proc");
const char linux_emul_path[] = "/compat/linux";
-/* DTrace init */
-LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
-
-/**
- * DTrace probes in this module.
- */
-LIN_SDT_PROBE_DEFINE5(util, linux_emul_convpath, entry, "const char *",
- "enum uio_seg", "char **", "int", "int");
-LIN_SDT_PROBE_DEFINE1(util, linux_emul_convpath, return, "int");
-LIN_SDT_PROBE_DEFINE1(util, linux_msg, entry, "const char *");
-LIN_SDT_PROBE_DEFINE0(util, linux_msg, return);
-LIN_SDT_PROBE_DEFINE2(util, linux_driver_get_name_dev, entry, "device_t",
- "const char *");
-LIN_SDT_PROBE_DEFINE0(util, linux_driver_get_name_dev, nullcall);
-LIN_SDT_PROBE_DEFINE1(util, linux_driver_get_name_dev, return, "char *");
-LIN_SDT_PROBE_DEFINE3(util, linux_driver_get_major_minor, entry, "char *",
- "int *", "int *");
-LIN_SDT_PROBE_DEFINE0(util, linux_driver_get_major_minor, nullcall);
-LIN_SDT_PROBE_DEFINE1(util, linux_driver_get_major_minor, notfound, "char *");
-LIN_SDT_PROBE_DEFINE3(util, linux_driver_get_major_minor, return, "int",
- "int", "int");
-LIN_SDT_PROBE_DEFINE0(util, linux_get_char_devices, entry);
-LIN_SDT_PROBE_DEFINE1(util, linux_get_char_devices, return, "char *");
-LIN_SDT_PROBE_DEFINE1(util, linux_free_get_char_devices, entry, "char *");
-LIN_SDT_PROBE_DEFINE0(util, linux_free_get_char_devices, return);
-LIN_SDT_PROBE_DEFINE1(util, linux_device_register_handler, entry,
- "struct linux_device_handler *");
-LIN_SDT_PROBE_DEFINE1(util, linux_device_register_handler, return, "int");
-LIN_SDT_PROBE_DEFINE1(util, linux_device_unregister_handler, entry,
- "struct linux_device_handler *");
-LIN_SDT_PROBE_DEFINE1(util, linux_device_unregister_handler, return, "int");
-
/*
* Search an alternate path before passing pathname arguments on to
* system calls. Useful for keeping a separate 'emulation tree'.
@@ -107,13 +73,9 @@ linux_emul_convpath(struct thread *td, const char *path, enum uio_seg pathseg,
{
int retval;
- LIN_SDT_PROBE5(util, linux_emul_convpath, entry, path, pathseg, pbuf,
- cflag, dfd);
-
retval = kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf,
cflag, dfd);
- LIN_SDT_PROBE1(util, linux_emul_convpath, return, retval);
return (retval);
}
@@ -123,16 +85,12 @@ linux_msg(const struct thread *td, const char *fmt, ...)
va_list ap;
struct proc *p;
- LIN_SDT_PROBE1(util, linux_msg, entry, fmt);
-
p = td->td_proc;
printf("linux: pid %d (%s): ", (int)p->p_pid, p->p_comm);
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
printf("\n");
-
- LIN_SDT_PROBE0(util, linux_msg, return);
}
struct device_element
@@ -155,24 +113,14 @@ linux_driver_get_name_dev(device_t dev)
struct device_element *de;
const char *device_name = device_get_name(dev);
- LIN_SDT_PROBE2(util, linux_driver_get_name_dev, entry, dev,
- device_name);
-
- if (device_name == NULL) {
- LIN_SDT_PROBE0(util, linux_driver_get_name_dev, nullcall);
- LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, NULL);
+ if (device_name == NULL)
return NULL;
- }
TAILQ_FOREACH(de, &devices, list) {
- if (strcmp(device_name, de->entry.bsd_driver_name) == 0) {
- LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return,
- de->entry.linux_driver_name);
+ if (strcmp(device_name, de->entry.bsd_driver_name) == 0)
return (de->entry.linux_driver_name);
- }
}
- LIN_SDT_PROBE1(util, linux_driver_get_name_dev, return, NULL);
- return NULL;
+ return (NULL);
}
int
@@ -180,15 +128,8 @@ linux_driver_get_major_minor(const char *node, int *major, int *minor)
{
struct device_element *de;
- LIN_SDT_PROBE3(util, linux_driver_get_major_minor, entry, node, major,
- minor);
-
- if (node == NULL || major == NULL || minor == NULL) {
- LIN_SDT_PROBE0(util, linux_driver_get_major_minor, nullcall);
- LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 1,
- 0, 0);
+ if (node == NULL || major == NULL || minor == NULL)
return 1;
- }
if (strlen(node) > strlen("pts/") &&
strncmp(node, "pts/", strlen("pts/")) == 0) {
@@ -203,25 +144,18 @@ linux_driver_get_major_minor(const char *node, int *major, int *minor)
*major = 136 + (devno / 256);
*minor = devno % 256;
- LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 0,
- *major, *minor);
- return 0;
+ return (0);
}
TAILQ_FOREACH(de, &devices, list) {
if (strcmp(node, de->entry.bsd_device_name) == 0) {
*major = de->entry.linux_major;
*minor = de->entry.linux_minor;
-
- LIN_SDT_PROBE3(util, linux_driver_get_major_minor,
- return, 0, *major, *minor);
- return 0;
+ return (0);
}
}
- LIN_SDT_PROBE1(util, linux_driver_get_major_minor, notfound, node);
- LIN_SDT_PROBE3(util, linux_driver_get_major_minor, return, 1, 0, 0);
- return 1;
+ return (1);
}
char *
@@ -232,8 +166,6 @@ linux_get_char_devices()
char formated[256];
int current_size = 0, string_size = 1024;
- LIN_SDT_PROBE0(util, linux_get_char_devices, entry);
-
string = malloc(string_size, M_LINUX, M_WAITOK);
string[0] = '\000';
last = "";
@@ -260,19 +192,14 @@ linux_get_char_devices()
}
}
- LIN_SDT_PROBE1(util, linux_get_char_devices, return, string);
- return string;
+ return (string);
}
void
linux_free_get_char_devices(char *string)
{
- LIN_SDT_PROBE1(util, linux_get_char_devices, entry, string);
-
free(string, M_LINUX);
-
- LIN_SDT_PROBE0(util, linux_get_char_devices, return);
}
static int linux_major_starting = 200;
@@ -282,13 +209,8 @@ linux_device_register_handler(struct linux_device_handler *d)
{
struct device_element *de;
- LIN_SDT_PROBE1(util, linux_device_register_handler, entry, d);
-
- if (d == NULL) {
- LIN_SDT_PROBE1(util, linux_device_register_handler, return,
- EINVAL);
+ if (d == NULL)
return (EINVAL);
- }
de = malloc(sizeof(*de), M_LINUX, M_WAITOK);
if (d->linux_major < 0) {
@@ -299,7 +221,6 @@ linux_device_register_handler(struct linux_device_handler *d)
/* Add the element to the list, sorted on span. */
TAILQ_INSERT_TAIL(&devices, de, list);
- LIN_SDT_PROBE1(util, linux_device_register_handler, return, 0);
return (0);
}
@@ -308,25 +229,17 @@ linux_device_unregister_handler(struct linux_device_handler *d)
{
struct device_element *de;
- LIN_SDT_PROBE1(util, linux_device_unregister_handler, entry, d);
-
- if (d == NULL) {
- LIN_SDT_PROBE1(util, linux_device_unregister_handler, return,
- EINVAL);
+ if (d == NULL)
return (EINVAL);
- }
TAILQ_FOREACH(de, &devices, list) {
if (bcmp(d, &de->entry, sizeof(*d)) == 0) {
TAILQ_REMOVE(&devices, de, list);
free(de, M_LINUX);
- LIN_SDT_PROBE1(util, linux_device_unregister_handler,
- return, 0);
return (0);
}
}
- LIN_SDT_PROBE1(util, linux_device_unregister_handler, return, EINVAL);
return (EINVAL);
}
diff --git a/sys/compat/linux/linux_util.h b/sys/compat/linux/linux_util.h
index 6be0392f75ac..a52a7b91d551 100644
--- a/sys/compat/linux/linux_util.h
+++ b/sys/compat/linux/linux_util.h
@@ -44,6 +44,11 @@
#include <sys/cdefs.h>
#include <sys/uio.h>
+MALLOC_DECLARE(M_LINUX);
+MALLOC_DECLARE(M_EPOLL);
+MALLOC_DECLARE(M_FUTEX);
+MALLOC_DECLARE(M_FUTEX_WP);
+
extern const char linux_emul_path[];
int linux_emul_convpath(struct thread *, const char *, enum uio_seg, char **, int, int);
@@ -115,7 +120,6 @@ void linux_free_get_char_devices(char *string);
#define LINUX_CTRFMT(nm, fmt) #nm"("fmt")"
#define LINUX_CTR6(f, m, p1, p2, p3, p4, p5, p6) do { \
- if (ldebug(f)) \
CTR6(KTR_LINUX, LINUX_CTRFMT(f, m), \
p1, p2, p3, p4, p5, p6); \
} while (0)
diff --git a/sys/compat/linux/linux_vdso.c b/sys/compat/linux/linux_vdso.c
new file mode 100644
index 000000000000..5ab0ee641617
--- /dev/null
+++ b/sys/compat/linux/linux_vdso.c
@@ -0,0 +1,244 @@
+/*-
+ * Copyright (c) 2013 Dmitry Chagin
+ * 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
+ * in this position and unchanged.
+ * 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 ``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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_compat.h"
+
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+#define __ELF_WORD_SIZE 32
+#else
+#define __ELF_WORD_SIZE 64
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/elf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/queue.h>
+#include <sys/sysent.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+#include <compat/linux/linux_vdso.h>
+
+SLIST_HEAD(, linux_vdso_sym) __elfN(linux_vdso_syms) =
+ SLIST_HEAD_INITIALIZER(__elfN(linux_vdso_syms));
+
+static int __elfN(symtabindex);
+static int __elfN(symstrindex);
+
+static void
+__elfN(linux_vdso_lookup)(Elf_Ehdr *, struct linux_vdso_sym *);
+
+
+void
+__elfN(linux_vdso_sym_init)(struct linux_vdso_sym *s)
+{
+
+ SLIST_INSERT_HEAD(&__elfN(linux_vdso_syms), s, sym);
+}
+
+vm_object_t
+__elfN(linux_shared_page_init)(char **mapping)
+{
+ vm_page_t m;
+ vm_object_t obj;
+ vm_offset_t addr;
+
+ obj = vm_pager_allocate(OBJT_PHYS, 0, PAGE_SIZE,
+ VM_PROT_DEFAULT, 0, NULL);
+ VM_OBJECT_WLOCK(obj);
+ m = vm_page_grab(obj, 0, VM_ALLOC_NOBUSY | VM_ALLOC_ZERO);
+ m->valid = VM_PAGE_BITS_ALL;
+ VM_OBJECT_WUNLOCK(obj);
+ addr = kva_alloc(PAGE_SIZE);
+ pmap_qenter(addr, &m, 1);
+ *mapping = (char *)addr;
+ return (obj);
+}
+
+void
+__elfN(linux_shared_page_fini)(vm_object_t obj)
+{
+
+ vm_object_deallocate(obj);
+}
+
+void
+__elfN(linux_vdso_fixup)(struct sysentvec *sv)
+{
+ Elf_Ehdr *ehdr;
+ Elf_Shdr *shdr;
+ int i;
+
+ ehdr = (Elf_Ehdr *) sv->sv_sigcode;
+
+ if (!IS_ELF(*ehdr) ||
+ ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS ||
+ ehdr->e_ident[EI_DATA] != ELF_TARG_DATA ||
+ ehdr->e_ident[EI_VERSION] != EV_CURRENT ||
+ ehdr->e_shoff == 0 ||
+ ehdr->e_shentsize != sizeof(Elf_Shdr))
+ panic("Linux invalid vdso header.\n");
+
+ if (ehdr->e_type != ET_DYN)
+ panic("Linux invalid vdso header.\n");
+
+ shdr = (Elf_Shdr *) ((caddr_t)ehdr + ehdr->e_shoff);
+
+ __elfN(symtabindex) = -1;
+ __elfN(symstrindex) = -1;
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ if (shdr[i].sh_size == 0)
+ continue;
+ if (shdr[i].sh_type == SHT_DYNSYM) {
+ __elfN(symtabindex) = i;
+ __elfN(symstrindex) = shdr[i].sh_link;
+ }
+ }
+
+ if (__elfN(symtabindex) == -1 || __elfN(symstrindex) == -1)
+ panic("Linux invalid vdso header.\n");
+
+ ehdr->e_ident[EI_OSABI] = ELFOSABI_LINUX;
+}
+
+void
+__elfN(linux_vdso_reloc)(struct sysentvec *sv, long vdso_adjust)
+{
+ struct linux_vdso_sym *lsym;
+ Elf_Ehdr *ehdr;
+ Elf_Phdr *phdr;
+ Elf_Shdr *shdr;
+ Elf_Dyn *dyn;
+ Elf_Sym *sym;
+ int i, symcnt;
+
+ ehdr = (Elf_Ehdr *) sv->sv_sigcode;
+
+ /* Adjust our so relative to the sigcode_base */
+ if (vdso_adjust != 0) {
+ ehdr->e_entry += vdso_adjust;
+ phdr = (Elf_Phdr *)((caddr_t)ehdr + ehdr->e_phoff);
+
+ /* phdrs */
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ phdr[i].p_vaddr += vdso_adjust;
+ if (phdr[i].p_type != PT_DYNAMIC)
+ continue;
+ dyn = (Elf_Dyn *)((caddr_t)ehdr + phdr[i].p_offset);
+ for(; dyn->d_tag != DT_NULL; dyn++) {
+ switch (dyn->d_tag) {
+ case DT_PLTGOT:
+ case DT_HASH:
+ case DT_STRTAB:
+ case DT_SYMTAB:
+ case DT_RELA:
+ case DT_INIT:
+ case DT_FINI:
+ case DT_REL:
+ case DT_DEBUG:
+ case DT_JMPREL:
+ case DT_VERSYM:
+ case DT_VERDEF:
+ case DT_VERNEED:
+ case DT_ADDRRNGLO ... DT_ADDRRNGHI:
+ dyn->d_un.d_ptr += vdso_adjust;
+ break;
+ case DT_ENCODING ... DT_LOOS-1:
+ case DT_LOOS ... DT_HIOS:
+ if (dyn->d_tag >= DT_ENCODING &&
+ (dyn->d_tag & 1) == 0)
+ dyn->d_un.d_ptr += vdso_adjust;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* sections */
+ shdr = (Elf_Shdr *)((caddr_t)ehdr + ehdr->e_shoff);
+ for(i = 0; i < ehdr->e_shnum; i++) {
+ if (!(shdr[i].sh_flags & SHF_ALLOC))
+ continue;
+ shdr[i].sh_addr += vdso_adjust;
+ if (shdr[i].sh_type != SHT_SYMTAB &&
+ shdr[i].sh_type != SHT_DYNSYM)
+ continue;
+
+ sym = (Elf_Sym *)((caddr_t)ehdr + shdr[i].sh_offset);
+ symcnt = shdr[i].sh_size / sizeof(*sym);
+
+ for(i = 0; i < symcnt; i++, sym++) {
+ if (sym->st_shndx == SHN_UNDEF ||
+ sym->st_shndx == SHN_ABS)
+ continue;
+ sym->st_value += vdso_adjust;
+ }
+ }
+ }
+
+ SLIST_FOREACH(lsym, &__elfN(linux_vdso_syms), sym)
+ __elfN(linux_vdso_lookup)(ehdr, lsym);
+}
+
+static void
+__elfN(linux_vdso_lookup)(Elf_Ehdr *ehdr, struct linux_vdso_sym *vsym)
+{
+ vm_offset_t strtab, symname;
+ uint32_t symcnt;
+ Elf_Shdr *shdr;
+ int i;
+
+ shdr = (Elf_Shdr *) ((caddr_t)ehdr + ehdr->e_shoff);
+
+ strtab = (vm_offset_t)((caddr_t)ehdr +
+ shdr[__elfN(symstrindex)].sh_offset);
+ Elf_Sym *sym = (Elf_Sym *)((caddr_t)ehdr +
+ shdr[__elfN(symtabindex)].sh_offset);
+ symcnt = shdr[__elfN(symtabindex)].sh_size / sizeof(*sym);
+
+ for (i = 0; i < symcnt; ++i, ++sym) {
+ symname = strtab + sym->st_name;
+ if (strncmp(vsym->symname, (char *)symname, vsym->size) == 0) {
+ *vsym->ptr = (uintptr_t)sym->st_value;
+ break;
+ }
+ }
+}
diff --git a/sys/compat/linux/linux_vdso.h b/sys/compat/linux/linux_vdso.h
new file mode 100644
index 000000000000..e11ee8ad07b0
--- /dev/null
+++ b/sys/compat/linux/linux_vdso.h
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2013 Dmitry Chagin
+ * 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
+ * in this position and unchanged.
+ * 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 ``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 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$
+ */
+
+#ifndef _LINUX_VDSO_H_
+#define _LINUX_VDSO_H_
+
+#include <sys/types.h>
+
+struct linux_vdso_sym {
+ SLIST_ENTRY(linux_vdso_sym) sym;
+ uint32_t size;
+ uintptr_t * ptr;
+ char symname[];
+};
+
+vm_object_t __elfN(linux_shared_page_init)(char **);
+void __elfN(linux_shared_page_fini)(vm_object_t);
+void __elfN(linux_vdso_fixup)(struct sysentvec *);
+void __elfN(linux_vdso_reloc)(struct sysentvec *, long);
+void __elfN(linux_vdso_sym_init)(struct linux_vdso_sym *);
+
+#define LINUX_VDSO_SYM_INTPTR(name) \
+uintptr_t name; \
+LINUX_VDSO_SYM_DEFINE(name)
+
+#define LINUX_VDSO_SYM_CHAR(name) \
+const char * name; \
+LINUX_VDSO_SYM_DEFINE(name)
+
+#define LINUX_VDSO_SYM_DEFINE(name) \
+static struct linux_vdso_sym name ## sym = { \
+ .symname = #name, \
+ .size = sizeof(#name), \
+ .ptr = (uintptr_t *)&name \
+}; \
+SYSINIT(__elfN(name ## _sym_init), SI_SUB_EXEC, \
+ SI_ORDER_FIRST, __elfN(linux_vdso_sym_init), &name ## sym); \
+struct __hack
+
+#endif /* _LINUX_VDSO_H_ */
diff --git a/sys/compat/linux/stats_timing.d b/sys/compat/linux/stats_timing.d
index d0b6f73c654c..1b60dc98689a 100644
--- a/sys/compat/linux/stats_timing.d
+++ b/sys/compat/linux/stats_timing.d
@@ -39,7 +39,6 @@
* possible for a given application
* - graph of longest running (CPU-time!) function in total
* - may help finding problem cases in the kernel code
- * - timing statistics for the emul_lock
* - graph of longest held (CPU-time!) locks
*/
diff --git a/sys/compat/svr4/imgact_svr4.c b/sys/compat/svr4/imgact_svr4.c
index f3bb09e51688..e61b49bb3640 100644
--- a/sys/compat/svr4/imgact_svr4.c
+++ b/sys/compat/svr4/imgact_svr4.c
@@ -109,7 +109,7 @@ exec_svr4_imgact(imgp)
*/
PROC_LOCK(imgp->proc);
if (a_out->a_text > maxtsiz ||
- a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA) ||
+ a_out->a_data + bss_size > lim_cur_proc(imgp->proc, RLIMIT_DATA) ||
racct_set(imgp->proc, RACCT_DATA, a_out->a_data + bss_size) != 0) {
PROC_UNLOCK(imgp->proc);
return (ENOMEM);
diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c
index c0da170a5e3b..1b4a35eb77e4 100644
--- a/sys/compat/svr4/svr4_misc.c
+++ b/sys/compat/svr4/svr4_misc.c
@@ -910,9 +910,7 @@ svr4_sys_ulimit(td, uap)
switch (uap->cmd) {
case SVR4_GFILLIM:
- PROC_LOCK(td->td_proc);
- *retval = lim_cur(td->td_proc, RLIMIT_FSIZE) / 512;
- PROC_UNLOCK(td->td_proc);
+ *retval = lim_cur(td, RLIMIT_FSIZE) / 512;
if (*retval == -1)
*retval = 0x7fffffff;
return 0;
@@ -922,17 +920,13 @@ svr4_sys_ulimit(td, uap)
struct rlimit krl;
krl.rlim_cur = uap->newlimit * 512;
- PROC_LOCK(td->td_proc);
- krl.rlim_max = lim_max(td->td_proc, RLIMIT_FSIZE);
- PROC_UNLOCK(td->td_proc);
+ krl.rlim_max = lim_max(td, RLIMIT_FSIZE);
error = kern_setrlimit(td, RLIMIT_FSIZE, &krl);
if (error)
return error;
- PROC_LOCK(td->td_proc);
- *retval = lim_cur(td->td_proc, RLIMIT_FSIZE);
- PROC_UNLOCK(td->td_proc);
+ *retval = lim_cur(td, RLIMIT_FSIZE);
if (*retval == -1)
*retval = 0x7fffffff;
return 0;
@@ -943,9 +937,7 @@ svr4_sys_ulimit(td, uap)
struct vmspace *vm = td->td_proc->p_vmspace;
register_t r;
- PROC_LOCK(td->td_proc);
- r = lim_cur(td->td_proc, RLIMIT_DATA);
- PROC_UNLOCK(td->td_proc);
+ r = lim_cur(td, RLIMIT_DATA);
if (r == -1)
r = 0x7fffffff;
@@ -957,9 +949,7 @@ svr4_sys_ulimit(td, uap)
}
case SVR4_GDESLIM:
- PROC_LOCK(td->td_proc);
- *retval = lim_cur(td->td_proc, RLIMIT_NOFILE);
- PROC_UNLOCK(td->td_proc);
+ *retval = lim_cur(td, RLIMIT_NOFILE);
if (*retval == -1)
*retval = 0x7fffffff;
return 0;
diff --git a/sys/compat/svr4/svr4_resource.c b/sys/compat/svr4/svr4_resource.c
index efa0bcf4757d..667ee88c1d3f 100644
--- a/sys/compat/svr4/svr4_resource.c
+++ b/sys/compat/svr4/svr4_resource.c
@@ -130,9 +130,7 @@ svr4_sys_getrlimit(td, uap)
if (rl == -1)
return EINVAL;
- PROC_LOCK(td->td_proc);
- lim_rlimit(td->td_proc, rl, &blim);
- PROC_UNLOCK(td->td_proc);
+ lim_rlimit(td, rl, &blim);
/*
* Our infinity, is their maxfiles.
@@ -181,9 +179,7 @@ svr4_sys_setrlimit(td, uap)
if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0)
return error;
- PROC_LOCK(td->td_proc);
- lim_rlimit(td->td_proc, rl, &curlim);
- PROC_UNLOCK(td->td_proc);
+ lim_rlimit(td, rl, &curlim);
/*
* if the limit is SVR4_RLIM_INFINITY, then we set it to our
@@ -228,9 +224,7 @@ svr4_sys_getrlimit64(td, uap)
if (rl == -1)
return EINVAL;
- PROC_LOCK(td->td_proc);
- lim_rlimit(td->td_proc, rl, &blim);
- PROC_UNLOCK(td->td_proc);
+ lim_rlimit(td, rl, &blim);
/*
* Our infinity, is their maxfiles.
@@ -279,9 +273,7 @@ svr4_sys_setrlimit64(td, uap)
if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0)
return error;
- PROC_LOCK(td->td_proc);
- lim_rlimit(td->td_proc, rl, &curlim);
- PROC_UNLOCK(td->td_proc);
+ lim_rlimit(td, rl, &curlim);
/*
* if the limit is SVR4_RLIM64_INFINITY, then we set it to our
diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c
index 561a838c507f..125a7d80c248 100644
--- a/sys/compat/svr4/svr4_sysvec.c
+++ b/sys/compat/svr4/svr4_sysvec.c
@@ -196,6 +196,7 @@ struct sysentvec svr4_sysvec = {
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = NULL,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
const char svr4_emul_path[] = "/compat/svr4";
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 8f00f59d9d7c..90fc66e95caa 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -156,6 +156,7 @@ options GEOM_GATE # Userland services.
options GEOM_JOURNAL # Journaling.
options GEOM_LABEL # Providers labelization.
options GEOM_LINUX_LVM # Linux LVM2 volumes
+options GEOM_MAP # Map based partitioning
options GEOM_MBR # DOS/MBR partitioning
options GEOM_MIRROR # Disk mirroring.
options GEOM_MULTIPATH # Disk multipath
@@ -176,6 +177,7 @@ options GEOM_RAID3 # RAID3 functionality.
options GEOM_SHSEC # Shared secret.
options GEOM_STRIPE # Disk striping.
options GEOM_SUNLABEL # Sun/Solaris partitioning
+options GEOM_UNCOMPRESS # Read-only compressed disks (lzma, zip)
options GEOM_UZIP # Read-only compressed disks
options GEOM_VINUM # Vinum logical volume manager
options GEOM_VIRSTOR # Virtual storage.
@@ -2980,6 +2982,9 @@ options RANDOM_DEBUG # Debugging messages
# Module to enable execution of application via emulators like QEMU
options IMAGACT_BINMISC
+# Intel em(4) driver
+options EM_MULTIQUEUE # Activate multiqueue features/disable MSI-X
+
# zlib I/O stream support
# This enables support for compressed core dumps.
options GZIO
diff --git a/sys/conf/files b/sys/conf/files
index 8d51fe55e9c5..0217e46bd1d7 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -104,11 +104,12 @@ cam/scsi/scsi_targ_bh.c optional targbh
cam/scsi/scsi_target.c optional targ
cam/scsi/smp_all.c optional scbus
# shared between zfs and dtrace
-cddl/compat/opensolaris/kern/opensolaris.c optional zfs compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_cmn_err.c optional zfs compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_kmem.c optional zfs compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_misc.c optional zfs compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_sunddi.c optional zfs compile-with "${ZFS_C}"
+cddl/compat/opensolaris/kern/opensolaris.c optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/compat/opensolaris/kern/opensolaris_cmn_err.c optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/compat/opensolaris/kern/opensolaris_kmem.c optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/compat/opensolaris/kern/opensolaris_misc.c optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/compat/opensolaris/kern/opensolaris_sunddi.c optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/compat/opensolaris/kern/opensolaris_taskq.c optional zfs | dtrace compile-with "${CDDL_C}"
# zfs specific
cddl/compat/opensolaris/kern/opensolaris_acl.c optional zfs compile-with "${ZFS_C}"
cddl/compat/opensolaris/kern/opensolaris_dtrace.c optional zfs compile-with "${ZFS_C}"
@@ -118,7 +119,6 @@ cddl/compat/opensolaris/kern/opensolaris_lookup.c optional zfs compile-with "$
cddl/compat/opensolaris/kern/opensolaris_policy.c optional zfs compile-with "${ZFS_C}"
cddl/compat/opensolaris/kern/opensolaris_string.c optional zfs compile-with "${ZFS_C}"
cddl/compat/opensolaris/kern/opensolaris_sysevent.c optional zfs compile-with "${ZFS_C}"
-cddl/compat/opensolaris/kern/opensolaris_taskq.c optional zfs compile-with "${ZFS_C}"
cddl/compat/opensolaris/kern/opensolaris_uio.c optional zfs compile-with "${ZFS_C}"
cddl/compat/opensolaris/kern/opensolaris_vfs.c optional zfs compile-with "${ZFS_C}"
cddl/compat/opensolaris/kern/opensolaris_vm.c optional zfs compile-with "${ZFS_C}"
@@ -242,6 +242,17 @@ cddl/contrib/opensolaris/uts/common/zmod/trees.c optional zfs compile-with "${
cddl/contrib/opensolaris/uts/common/zmod/zmod.c optional zfs compile-with "${ZFS_C}"
cddl/contrib/opensolaris/uts/common/zmod/zmod_subr.c optional zfs compile-with "${ZFS_C}"
cddl/contrib/opensolaris/uts/common/zmod/zutil.c optional zfs compile-with "${ZFS_C}"
+# dtrace specific
+cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c optional dtrace compile-with "${DTRACE_C}" \
+ warning "kernel contains CDDL licensed DTRACE"
+cddl/dev/dtmalloc/dtmalloc.c optional dtmalloc | dtraceall compile-with "${CDDL_C}"
+cddl/dev/lockstat/lockstat.c optional dtrace_lockstat | dtraceall compile-with "${CDDL_C}"
+cddl/dev/profile/profile.c optional dtrace_profile | dtraceall compile-with "${CDDL_C}"
+cddl/dev/sdt/sdt.c optional dtrace_sdt | dtraceall compile-with "${CDDL_C}"
+cddl/dev/fbt/fbt.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
+cddl/dev/systrace/systrace.c optional dtrace_systrace | dtraceall compile-with "${CDDL_C}"
+cddl/dev/prototype.c optional dtrace_prototype | dtraceall compile-with "${CDDL_C}"
+fs/nfsclient/nfs_clkdtrace.c optional dtnfscl nfscl | dtraceall nfscl compile-with "${CDDL_C}"
compat/freebsd32/freebsd32_capability.c optional compat_freebsd32
compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32
compat/freebsd32/freebsd32_misc.c optional compat_freebsd32
@@ -1427,6 +1438,8 @@ dev/hptiop/hptiop.c optional hptiop scbus
dev/hwpmc/hwpmc_logging.c optional hwpmc
dev/hwpmc/hwpmc_mod.c optional hwpmc
dev/hwpmc/hwpmc_soft.c optional hwpmc
+dev/ichiic/ig4_iic.c optional ichiic
+dev/ichiic/ig4_pci.c optional ichiic pci
dev/ichsmb/ichsmb.c optional ichsmb
dev/ichsmb/ichsmb_pci.c optional ichsmb pci
dev/ida/ida.c optional ida
@@ -2024,6 +2037,7 @@ dev/pci/isa_pci.c optional pci isa
dev/pci/pci.c optional pci
dev/pci/pci_if.m standard
dev/pci/pci_iov.c optional pci pci_iov
+dev/pci/pci_iov_if.m standard
dev/pci/pci_iov_schema.c optional pci pci_iov
dev/pci/pci_pci.c optional pci
dev/pci/pci_subr.c optional pci
@@ -2156,37 +2170,6 @@ dev/sdhci/sdhci.c optional sdhci
dev/sdhci/sdhci_if.m optional sdhci
dev/sdhci/sdhci_pci.c optional sdhci pci
dev/sf/if_sf.c optional sf pci
-dev/sfxge/common/efx_bootcfg.c optional sfxge pci
-dev/sfxge/common/efx_ev.c optional sfxge pci
-dev/sfxge/common/efx_filter.c optional sfxge pci
-dev/sfxge/common/efx_intr.c optional sfxge pci
-dev/sfxge/common/efx_mac.c optional sfxge pci
-dev/sfxge/common/efx_mcdi.c optional sfxge pci
-dev/sfxge/common/efx_mon.c optional sfxge pci
-dev/sfxge/common/efx_nic.c optional sfxge pci
-dev/sfxge/common/efx_nvram.c optional sfxge pci
-dev/sfxge/common/efx_phy.c optional sfxge pci
-dev/sfxge/common/efx_port.c optional sfxge pci
-dev/sfxge/common/efx_rx.c optional sfxge pci
-dev/sfxge/common/efx_sram.c optional sfxge pci
-dev/sfxge/common/efx_tx.c optional sfxge pci
-dev/sfxge/common/efx_vpd.c optional sfxge pci
-dev/sfxge/common/efx_wol.c optional sfxge pci
-dev/sfxge/common/siena_mac.c optional sfxge pci
-dev/sfxge/common/siena_mon.c optional sfxge pci
-dev/sfxge/common/siena_nic.c optional sfxge pci
-dev/sfxge/common/siena_nvram.c optional sfxge pci
-dev/sfxge/common/siena_phy.c optional sfxge pci
-dev/sfxge/common/siena_sram.c optional sfxge pci
-dev/sfxge/common/siena_vpd.c optional sfxge pci
-dev/sfxge/sfxge.c optional sfxge pci
-dev/sfxge/sfxge_dma.c optional sfxge pci
-dev/sfxge/sfxge_ev.c optional sfxge pci
-dev/sfxge/sfxge_intr.c optional sfxge pci
-dev/sfxge/sfxge_mcdi.c optional sfxge pci
-dev/sfxge/sfxge_port.c optional sfxge pci
-dev/sfxge/sfxge_rx.c optional sfxge pci
-dev/sfxge/sfxge_tx.c optional sfxge pci
dev/sge/if_sge.c optional sge pci
dev/si/si.c optional si
dev/si/si2_z280.c optional si
@@ -2589,6 +2572,7 @@ dev/usb/template/usb_template_msc.c optional usb_template
dev/usb/template/usb_template_mtp.c optional usb_template
dev/usb/template/usb_template_phone.c optional usb_template
dev/usb/template/usb_template_serialnet.c optional usb_template
+dev/usb/template/usb_template_midi.c optional usb_template
#
# USB video drivers
#
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 8aadcf5fba2f..08fb59b50aa4 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -20,6 +20,18 @@ linux32_assym.h optional compat_linux32 \
no-obj no-implicit-rule before-depend \
clean "linux32_assym.h"
#
+linux32_locore.o optional compat_linux32 \
+ dependency "linux32_assym.h $S/amd64/linux32/linux32_locore.s" \
+ compile-with "${CC} -x assembler-with-cpp -DLOCORE -m32 -shared -s -pipe -I. -I$S -Werror -Wall -fno-common -nostdinc -nostdlib -Wl,-T$S/amd64/linux32/linux32_vdso.lds.s -Wl,-soname=linux32_vdso.so,--eh-frame-hdr,-fPIC,-warn-common ${.IMPSRC} -o ${.TARGET}" \
+ no-obj no-implicit-rule \
+ clean "linux32_locore.o"
+#
+linux32_vdso.so optional compat_linux32 \
+ dependency "linux32_locore.o" \
+ compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 linux32_locore.o ${.TARGET}" \
+ no-implicit-rule \
+ clean "linux32_vdso.so"
+#
ia32_genassym.o standard \
dependency "$S/compat/ia32/ia32_genassym.c" \
compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \
@@ -126,7 +138,12 @@ amd64/amd64/uio_machdep.c standard
amd64/amd64/uma_machdep.c standard
amd64/amd64/vm_machdep.c standard
amd64/pci/pci_cfgreg.c optional pci
-cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S optional zfs compile-with "${ZFS_S}"
+cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S optional zfs | dtrace compile-with "${ZFS_S}"
+cddl/dev/dtrace/amd64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/amd64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/x86/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
+cddl/dev/dtrace/x86/dis_tables.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
+cddl/dev/dtrace/amd64/instr_size.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
crypto/aesni/aeskeys_amd64.S optional aesni
crypto/aesni/aesni.c optional aesni
aesni_ghash.o optional aesni \
@@ -292,37 +309,52 @@ dev/qlxgbe/ql_isr.c optional qlxgbe pci
dev/qlxgbe/ql_misc.c optional qlxgbe pci
dev/qlxgbe/ql_os.c optional qlxgbe pci
dev/qlxgbe/ql_reset.c optional qlxgbe pci
-dev/sfxge/common/efx_bootcfg.c optional sfxge inet pci
-dev/sfxge/common/efx_ev.c optional sfxge inet pci
-dev/sfxge/common/efx_filter.c optional sfxge inet pci
-dev/sfxge/common/efx_intr.c optional sfxge inet pci
-dev/sfxge/common/efx_mac.c optional sfxge inet pci
-dev/sfxge/common/efx_mcdi.c optional sfxge inet pci
-dev/sfxge/common/efx_mon.c optional sfxge inet pci
-dev/sfxge/common/efx_nic.c optional sfxge inet pci
-dev/sfxge/common/efx_nvram.c optional sfxge inet pci
-dev/sfxge/common/efx_phy.c optional sfxge inet pci
-dev/sfxge/common/efx_port.c optional sfxge inet pci
-dev/sfxge/common/efx_rx.c optional sfxge inet pci
-dev/sfxge/common/efx_sram.c optional sfxge inet pci
-dev/sfxge/common/efx_tx.c optional sfxge inet pci
-dev/sfxge/common/efx_vpd.c optional sfxge inet pci
-dev/sfxge/common/efx_wol.c optional sfxge inet pci
-dev/sfxge/common/siena_mac.c optional sfxge inet pci
-dev/sfxge/common/siena_mon.c optional sfxge inet pci
-dev/sfxge/common/siena_nic.c optional sfxge inet pci
-dev/sfxge/common/siena_nvram.c optional sfxge inet pci
-dev/sfxge/common/siena_phy.c optional sfxge inet pci
-dev/sfxge/common/siena_sram.c optional sfxge inet pci
-dev/sfxge/common/siena_vpd.c optional sfxge inet pci
-dev/sfxge/sfxge.c optional sfxge inet pci
-dev/sfxge/sfxge_dma.c optional sfxge inet pci
-dev/sfxge/sfxge_ev.c optional sfxge inet pci
-dev/sfxge/sfxge_intr.c optional sfxge inet pci
-dev/sfxge/sfxge_mcdi.c optional sfxge inet pci
-dev/sfxge/sfxge_port.c optional sfxge inet pci
-dev/sfxge/sfxge_rx.c optional sfxge inet pci
-dev/sfxge/sfxge_tx.c optional sfxge inet pci
+dev/sfxge/common/efx_bootcfg.c optional sfxge pci
+dev/sfxge/common/efx_crc32.c optional sfxge pci
+dev/sfxge/common/efx_ev.c optional sfxge pci
+dev/sfxge/common/efx_filter.c optional sfxge pci
+dev/sfxge/common/efx_hash.c optional sfxge pci
+dev/sfxge/common/efx_intr.c optional sfxge pci
+dev/sfxge/common/efx_mac.c optional sfxge pci
+dev/sfxge/common/efx_mcdi.c optional sfxge pci
+dev/sfxge/common/efx_mon.c optional sfxge pci
+dev/sfxge/common/efx_nic.c optional sfxge pci
+dev/sfxge/common/efx_nvram.c optional sfxge pci
+dev/sfxge/common/efx_phy.c optional sfxge pci
+dev/sfxge/common/efx_port.c optional sfxge pci
+dev/sfxge/common/efx_rx.c optional sfxge pci
+dev/sfxge/common/efx_sram.c optional sfxge pci
+dev/sfxge/common/efx_tx.c optional sfxge pci
+dev/sfxge/common/efx_vpd.c optional sfxge pci
+dev/sfxge/common/efx_wol.c optional sfxge pci
+dev/sfxge/common/hunt_ev.c optional sfxge pci
+dev/sfxge/common/hunt_filter.c optional sfxge pci
+dev/sfxge/common/hunt_intr.c optional sfxge pci
+dev/sfxge/common/hunt_mac.c optional sfxge pci
+dev/sfxge/common/hunt_mcdi.c optional sfxge pci
+dev/sfxge/common/hunt_nic.c optional sfxge pci
+dev/sfxge/common/hunt_nvram.c optional sfxge pci
+dev/sfxge/common/hunt_phy.c optional sfxge pci
+dev/sfxge/common/hunt_rx.c optional sfxge pci
+dev/sfxge/common/hunt_sram.c optional sfxge pci
+dev/sfxge/common/hunt_tx.c optional sfxge pci
+dev/sfxge/common/hunt_vpd.c optional sfxge pci
+dev/sfxge/common/siena_mac.c optional sfxge pci
+dev/sfxge/common/siena_mcdi.c optional sfxge pci
+dev/sfxge/common/siena_nic.c optional sfxge pci
+dev/sfxge/common/siena_nvram.c optional sfxge pci
+dev/sfxge/common/siena_phy.c optional sfxge pci
+dev/sfxge/common/siena_sram.c optional sfxge pci
+dev/sfxge/common/siena_vpd.c optional sfxge pci
+dev/sfxge/sfxge.c optional sfxge pci
+dev/sfxge/sfxge_dma.c optional sfxge pci
+dev/sfxge/sfxge_ev.c optional sfxge pci
+dev/sfxge/sfxge_intr.c optional sfxge pci
+dev/sfxge/sfxge_mcdi.c optional sfxge pci
+dev/sfxge/sfxge_nvram.c optional sfxge pci
+dev/sfxge/sfxge_port.c optional sfxge pci
+dev/sfxge/sfxge_rx.c optional sfxge pci
+dev/sfxge/sfxge_tx.c optional sfxge pci
dev/sio/sio.c optional sio
dev/sio/sio_isa.c optional sio isa
dev/sio/sio_pccard.c optional sio pccard
@@ -473,8 +505,6 @@ compat/linsysfs/linsysfs.c optional linsysfs
# Linux/i386 binary support
#
amd64/linux32/linux32_dummy.c optional compat_linux32
-amd64/linux32/linux32_locore.s optional compat_linux32 \
- dependency "linux32_assym.h"
amd64/linux32/linux32_machdep.c optional compat_linux32
amd64/linux32/linux32_support.s optional compat_linux32 \
dependency "linux32_assym.h"
@@ -497,6 +527,10 @@ compat/linux/linux_time.c optional compat_linux32
compat/linux/linux_timer.c optional compat_linux32
compat/linux/linux_uid16.c optional compat_linux32
compat/linux/linux_util.c optional compat_linux32
+compat/linux/linux_vdso.c optional compat_linux32
+compat/linux/linux_common.c optional compat_linux32
+compat/linux/linux_event.c optional compat_linux32
+compat/linux/linux.c optional compat_linux32
dev/amr/amr_linux.c optional compat_linux32 amr
dev/mfi/mfi_linux.c optional compat_linux32 mfi
#
diff --git a/sys/conf/files.arm b/sys/conf/files.arm
index a406d331fb60..f49f455155a8 100644
--- a/sys/conf/files.arm
+++ b/sys/conf/files.arm
@@ -78,7 +78,10 @@ board_id.h standard \
compile-with "${AWK} -f $S/arm/conf/genboardid.awk $S/arm/conf/mach-types > board_id.h" \
no-obj no-implicit-rule before-depend \
clean "board_id.h"
-cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs compile-with "${ZFS_C}"
+cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs | dtrace compile-with "${CDDL_C}"
+cddl/dev/dtrace/arm/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/arm/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/arm/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
dev/fb/fb.c optional sc
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index 8bdc93a93457..a32d8d615fc6 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -2,6 +2,9 @@
arm/arm/devmap.c standard
arm/arm/generic_timer.c standard
arm/arm/pmu.c standard
+arm64/acpica/acpi_machdep.c optional acpi
+arm64/acpica/OsdEnvironment.c optional acpi
+arm64/acpica/acpi_wakeup.c optional acpi
arm64/arm64/autoconf.c standard
arm64/arm64/bcopy.c standard
arm64/arm64/bus_machdep.c standard
@@ -20,6 +23,8 @@ arm64/arm64/dump_machdep.c standard
arm64/arm64/elf_machdep.c standard
arm64/arm64/exception.S standard
arm64/arm64/gic.c standard
+arm64/arm64/gic_acpi.c optional acpi
+arm64/arm64/gic_fdt.c optional fdt
arm64/arm64/gic_v3.c standard
arm64/arm64/gic_v3_fdt.c optional fdt
arm64/arm64/identcpu.c standard
@@ -38,12 +43,15 @@ arm64/arm64/swtch.S standard
arm64/arm64/sys_machdep.c standard
arm64/arm64/trap.c standard
arm64/arm64/uio_machdep.c standard
+arm64/arm64/unwind.c optional ddb | kdtrace_hooks
arm64/arm64/vfp.c standard
arm64/arm64/vm_machdep.c standard
+dev/acpica/acpi_if.m optional acpi
dev/fdt/fdt_arm64.c optional fdt
dev/hwpmc/hwpmc_arm64.c optional hwpmc
dev/hwpmc/hwpmc_arm64_md.c optional hwpmc
dev/ofw/ofw_cpu.c optional fdt
+dev/pci/pci_host_generic.c optional pci fdt
dev/psci/psci.c optional psci
dev/psci/psci_arm64.S optional psci
dev/uart/uart_cpu_fdt.c optional uart fdt
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 68dd6a9aea4e..ebfce07280ff 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -19,6 +19,18 @@ linux_assym.h optional compat_linux \
no-obj no-implicit-rule before-depend \
clean "linux_assym.h"
#
+linux_locore.o optional compat_linux \
+ dependency "linux_assym.h $S/i386/linux/linux_locore.s" \
+ compile-with "${CC} -x assembler-with-cpp -DLOCORE -shared -s -pipe -I. -I$S -Werror -Wall -fno-common -nostdinc -nostdlib -Wl,-T$S/i386/linux/linux_vdso.lds.s -Wl,-soname=linux_vdso.so,--eh-frame-hdr,-fPIC,-warn-common ${.IMPSRC} -o ${.TARGET}" \
+ no-obj no-implicit-rule \
+ clean "linux_locore.o"
+#
+linux_vdso.so optional compat_linux \
+ dependency "linux_locore.o" \
+ compile-with "${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd --binary-architecture i386 linux_locore.o ${.TARGET}" \
+ no-implicit-rule \
+ clean "linux_vdso.so"
+#
svr4_genassym.o optional compat_svr4 \
dependency "$S/i386/svr4/svr4_genassym.c" \
compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \
@@ -66,9 +78,15 @@ hptrr_lib.o optional hptrr \
compile-with "uudecode < $S/dev/hptrr/i386-elf.hptrr_lib.o.uu" \
no-implicit-rule
#
-cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S optional zfs compile-with "${ZFS_S}"
+cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S optional zfs | dtrace compile-with "${ZFS_S}"
+cddl/dev/dtrace/i386/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/i386/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/x86/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
+cddl/dev/dtrace/x86/dis_tables.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
+cddl/dev/dtrace/i386/instr_size.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
compat/linprocfs/linprocfs.c optional linprocfs
compat/linsysfs/linsysfs.c optional linsysfs
+compat/linux/linux_event.c optional compat_linux
compat/linux/linux_emul.c optional compat_linux
compat/linux/linux_file.c optional compat_linux
compat/linux/linux_fork.c optional compat_linux
@@ -86,6 +104,8 @@ compat/linux/linux_time.c optional compat_linux
compat/linux/linux_timer.c optional compat_linux
compat/linux/linux_uid16.c optional compat_linux
compat/linux/linux_util.c optional compat_linux
+compat/linux/linux_vdso.c optional compat_linux
+compat/linux/linux.c optional compat_linux
compat/ndis/kern_ndis.c optional ndisapi pci
compat/ndis/kern_windrv.c optional ndisapi pci
compat/ndis/subr_hal.c optional ndisapi pci
@@ -490,8 +510,6 @@ i386/isa/prof_machdep.c optional profiling-routine
i386/isa/spic.c optional spic
i386/linux/imgact_linux.c optional compat_linux
i386/linux/linux_dummy.c optional compat_linux
-i386/linux/linux_locore.s optional compat_linux \
- dependency "linux_assym.h"
i386/linux/linux_machdep.c optional compat_linux
i386/linux/linux_ptrace.c optional compat_linux
i386/linux/linux_support.s optional compat_linux \
diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98
index ae165fcd3b85..28a94a8099cd 100644
--- a/sys/conf/files.pc98
+++ b/sys/conf/files.pc98
@@ -21,6 +21,18 @@ linux_assym.h optional compat_linux \
no-obj no-implicit-rule before-depend \
clean "linux_assym.h"
#
+linux_locore.o optional compat_linux \
+ dependency "linux_assym.h $S/i386/linux/linux_locore.s" \
+ compile-with "${CC} -x assembler-with-cpp -DLOCORE -shared -s -pipe -I. -I$S -Werror -Wall -fno-common -nostdinc -nostdlib -Wl,-T$S/i386/linux/linux_vdso.lds.s -Wl,-soname=linux_vdso.so,--eh-frame-hdr,-fPIC,-warn-common ${.IMPSRC} -o ${.TARGET}" \
+ no-obj no-implicit-rule \
+ clean "linux_locore.o"
+#
+linux_vdso.so optional compat_linux \
+ dependency "linux_locore.o" \
+ compile-with "${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd --binary-architecture i386 linux_locore.o ${.TARGET}" \
+ no-implicit-rule \
+ clean "linux_vdso.so"
+#
svr4_genassym.o optional compat_svr4 \
dependency "$S/i386/svr4/svr4_genassym.c" \
compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \
@@ -41,6 +53,7 @@ ukbdmap.h optional ukbd_dflt_keymap \
cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S optional zfs compile-with "${ZFS_S}"
compat/linprocfs/linprocfs.c optional linprocfs
compat/linsysfs/linsysfs.c optional linsysfs
+compat/linux/linux_event.c optional compat_linux
compat/linux/linux_emul.c optional compat_linux
compat/linux/linux_file.c optional compat_linux
compat/linux/linux_fork.c optional compat_linux
@@ -58,6 +71,8 @@ compat/linux/linux_time.c optional compat_linux
compat/linux/linux_timer.c optional compat_linux
compat/linux/linux_uid16.c optional compat_linux
compat/linux/linux_util.c optional compat_linux
+compat/linux/linux_vdso.c optional compat_linux
+compat/linux/linux.c optional compat_linux
compat/svr4/imgact_svr4.c optional compat_svr4
compat/svr4/svr4_fcntl.c optional compat_svr4
compat/svr4/svr4_filio.c optional compat_svr4
@@ -192,8 +207,6 @@ i386/isa/pmtimer.c optional pmtimer
i386/isa/prof_machdep.c optional profiling-routine
i386/linux/imgact_linux.c optional compat_linux
i386/linux/linux_dummy.c optional compat_linux
-i386/linux/linux_locore.s optional compat_linux \
- dependency "linux_assym.h"
i386/linux/linux_machdep.c optional compat_linux
i386/linux/linux_ptrace.c optional compat_linux
i386/linux/linux_support.s optional compat_linux \
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index 4158f2cb7ab1..167fa4236310 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -15,8 +15,11 @@ font.h optional sc \
clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8"
#
# There is only an asm version on ppc64.
-cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs powerpc compile-with "${ZFS_C}"
-cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S optional zfs powerpc64 compile-with "${ZFS_S}"
+cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs powerpc | dtrace powerpc compile-with "${ZFS_C}"
+cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S optional zfs powerpc64 | dtrace powerpc64 compile-with "${ZFS_S}"
+cddl/dev/dtrace/powerpc/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
+cddl/dev/dtrace/powerpc/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}"
+cddl/dev/fbt/powerpc/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
dev/bm/if_bm.c optional bm powermac
diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk
index 8f7abaf36063..28ea4530c887 100644
--- a/sys/conf/kern.post.mk
+++ b/sys/conf/kern.post.mk
@@ -184,11 +184,11 @@ genassym.o: $S/$M/$M/genassym.c
${SYSTEM_OBJS} genassym.o vers.o: opt_global.h
-# We have "special" -I include paths for opensolaris/zfs files in 'depend'.
-CFILES_NOZFS= ${CFILES:N*/opensolaris/*}
-SFILES_NOZFS= ${SFILES:N*/opensolaris/*}
-CFILES_ZFS= ${CFILES:M*/opensolaris/*}
-SFILES_ZFS= ${SFILES:M*/opensolaris/*}
+# We have "special" -I include paths for zfs/dtrace files in 'depend'.
+CFILES_NOCDDL= ${CFILES:N*/cddl/*:N*fs/nfsclient/nfs_clkdtrace*}
+SFILES_NOCDDL= ${SFILES:N*/cddl/*}
+CFILES_CDDL= ${CFILES:M*/cddl/*}
+SFILES_CDDL= ${SFILES:M*/cddl/*}
kernel-depend: .depend
# The argument list can be very long, so use make -V and xargs to
@@ -198,13 +198,13 @@ SRCS= assym.s vnode_if.h ${BEFORE_DEPEND} ${CFILES} \
${MFILES:T:S/.m$/.h/}
.depend: .PRECIOUS ${SRCS}
rm -f .newdep
- ${MAKE} -V CFILES_NOZFS -V SYSTEM_CFILES -V GEN_CFILES | \
+ ${MAKE} -V CFILES_NOCDDL -V SYSTEM_CFILES -V GEN_CFILES | \
MKDEP_CPP="${CC} -E" CC="${CC}" xargs mkdep -a -f .newdep ${CFLAGS}
- ${MAKE} -V CFILES_ZFS | \
- MKDEP_CPP="${CC} -E" CC="${CC}" xargs mkdep -a -f .newdep ${ZFS_CFLAGS}
- ${MAKE} -V SFILES_NOZFS | \
+ ${MAKE} -V CFILES_CDDL | \
+ MKDEP_CPP="${CC} -E" CC="${CC}" xargs mkdep -a -f .newdep ${ZFS_CFLAGS} ${FBT_CFLAGS} ${DTRACE_CFLAGS}
+ ${MAKE} -V SFILES_NOCDDL | \
MKDEP_CPP="${CC} -E" xargs mkdep -a -f .newdep ${ASM_CFLAGS}
- ${MAKE} -V SFILES_ZFS | \
+ ${MAKE} -V SFILES_CDDL | \
MKDEP_CPP="${CC} -E" xargs mkdep -a -f .newdep ${ZFS_ASM_CFLAGS}
rm -f .depend
mv .newdep .depend
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index 8c3b9c6e942f..3081edcaae64 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -139,13 +139,34 @@ NORMAL_FW= uudecode -o ${.TARGET} ${.ALLSRC}
NORMAL_FWO= ${LD} -b binary --no-warn-mismatch -d -warn-common -r \
-o ${.TARGET} ${.ALLSRC:M*.fw}
+# Common for dtrace / zfs
+CDDL_CFLAGS= -DFREEBSD_NAMECACHE -nostdinc -I$S/cddl/compat/opensolaris -I$S/cddl/contrib/opensolaris/uts/common -I$S -I$S/cddl/contrib/opensolaris/common ${CFLAGS} -Wno-unknown-pragmas -Wno-missing-prototypes -Wno-undef -Wno-strict-prototypes -Wno-cast-qual -Wno-parentheses -Wno-redundant-decls -Wno-missing-braces -Wno-uninitialized -Wno-unused -Wno-inline -Wno-switch -Wno-pointer-arith -Wno-unknown-pragmas
+CDDL_CFLAGS+= -include $S/cddl/compat/opensolaris/sys/debug_compat.h
+CDDL_C= ${CC} -c ${CDDL_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
+
# Special flags for managing the compat compiles for ZFS
-ZFS_CFLAGS= -DFREEBSD_NAMECACHE -DBUILDING_ZFS -nostdinc -I$S/cddl/compat/opensolaris -I$S/cddl/contrib/opensolaris/uts/common/fs/zfs -I$S/cddl/contrib/opensolaris/uts/common/zmod -I$S/cddl/contrib/opensolaris/uts/common -I$S -I$S/cddl/contrib/opensolaris/common/zfs -I$S/cddl/contrib/opensolaris/common ${CFLAGS} -Wno-unknown-pragmas -Wno-missing-prototypes -Wno-undef -Wno-strict-prototypes -Wno-cast-qual -Wno-parentheses -Wno-redundant-decls -Wno-missing-braces -Wno-uninitialized -Wno-unused -Wno-inline -Wno-switch -Wno-pointer-arith -Wno-unknown-pragmas
-ZFS_CFLAGS+= -include $S/cddl/compat/opensolaris/sys/debug_compat.h
+ZFS_CFLAGS= -DBUILDING_ZFS -I$S/cddl/contrib/opensolaris/uts/common/fs/zfs -I$S/cddl/contrib/opensolaris/uts/common/zmod -I$S/cddl/contrib/opensolaris/common/zfs ${CDDL_CFLAGS}
ZFS_ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${ZFS_CFLAGS}
ZFS_C= ${CC} -c ${ZFS_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
ZFS_S= ${CC} -c ${ZFS_ASM_CFLAGS} ${WERROR} ${.IMPSRC}
+# Special flags for managing the compat compiles for DTrace
+DTRACE_CFLAGS= -DBUILDING_DTRACE ${CDDL_CFLAGS} -I$S/cddl/dev/dtrace -I$S/cddl/dev/dtrace/${MACHINE_CPUARCH}
+.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
+DTRACE_CFLAGS+= -I$S/cddl/contrib/opensolaris/uts/intel -I$S/cddl/dev/dtrace/x86
+.endif
+DTRACE_CFLAGS+= -I$S/cddl/contrib/opensolaris/common/util -I$S -DDIS_MEM -DSMP
+DTRACE_ASM_CFLAGS= -x assembler-with-cpp -DLOCORE ${DTRACE_CFLAGS}
+DTRACE_C= ${CC} -c ${DTRACE_CFLAGS} ${CDDL_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
+DTRACE_S= ${CC} -c ${DTRACE_ASM_CFLAGS} ${CDDL_CFLAGS} ${WERROR} ${.IMPSRC}
+
+# Special flags for managing the compat compiles for DTrace/FBT
+FBT_CFLAGS= -DBUILDING_DTRACE -nostdinc -I$S/cddl/dev/fbt/${MACHINE_CPUARCH} -I$S/cddl/dev/fbt -I$S/cddl/compat/opensolaris -I$S/cddl/contrib/opensolaris/uts/common -I$S ${CDDL_CFLAGS}
+.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
+FBT_CFLAGS+= -I$S/cddl/dev/fbt/x86
+.endif
+FBT_C= ${CC} -c ${FBT_CFLAGS} ${CDDL_CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
+
.if ${MK_CTF} != "no"
NORMAL_CTFCONVERT= ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.elif ${MAKE_VERSION} >= 5201111300
diff --git a/sys/conf/kmod.mk b/sys/conf/kmod.mk
index ea2a6289a032..28b95c5ccc18 100644
--- a/sys/conf/kmod.mk
+++ b/sys/conf/kmod.mk
@@ -346,7 +346,7 @@ MFILES?= dev/acpica/acpi_if.m dev/acpi_support/acpi_wmi_if.m \
dev/mbox/mbox_if.m dev/mmc/mmcbr_if.m dev/mmc/mmcbus_if.m \
dev/mii/miibus_if.m dev/mvs/mvs_if.m dev/ofw/ofw_bus_if.m \
dev/pccard/card_if.m dev/pccard/power_if.m dev/pci/pci_if.m \
- dev/pci/pcib_if.m dev/ppbus/ppbus_if.m \
+ dev/pci/pci_iov_if.m dev/pci/pcib_if.m dev/ppbus/ppbus_if.m \
dev/sdhci/sdhci_if.m dev/smbus/smbus_if.m dev/spibus/spibus_if.m \
dev/sound/pci/hda/hdac_if.m \
dev/sound/pcm/ac97_if.m dev/sound/pcm/channel_if.m \
diff --git a/sys/conf/options b/sys/conf/options
index eabd73c0e69f..511e57c0be5e 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -108,6 +108,7 @@ GEOM_JOURNAL opt_geom.h
GEOM_LABEL opt_geom.h
GEOM_LABEL_GPT opt_geom.h
GEOM_LINUX_LVM opt_geom.h
+GEOM_MAP opt_geom.h
GEOM_MBR opt_geom.h
GEOM_MIRROR opt_geom.h
GEOM_MULTIPATH opt_geom.h
@@ -940,3 +941,6 @@ RCTL opt_global.h
RANDOM_YARROW opt_random.h
RANDOM_FORTUNA opt_random.h
RANDOM_DEBUG opt_random.h
+
+# Intel em(4) driver
+EM_MULTIQUEUE opt_em.h
diff --git a/sys/conf/options.arm b/sys/conf/options.arm
index 9926706a6b2c..57cef6a18dc6 100644
--- a/sys/conf/options.arm
+++ b/sys/conf/options.arm
@@ -22,6 +22,7 @@ CPU_XSCALE_IXP425 opt_global.h
CPU_XSCALE_IXP435 opt_global.h
CPU_XSCALE_PXA2X0 opt_global.h
DEV_GIC opt_global.h
+EFI opt_platform.h
FLASHADDR opt_global.h
GIC_DEFAULT_ICFGR_INIT opt_global.h
IPI_IRQ_START opt_smp.h
diff --git a/sys/contrib/dev/acpica/common/ahuuids.c b/sys/contrib/dev/acpica/common/ahuuids.c
index a96ab8f4f577..eeec8b855b4e 100644
--- a/sys/contrib/dev/acpica/common/ahuuids.c
+++ b/sys/contrib/dev/acpica/common/ahuuids.c
@@ -43,6 +43,7 @@
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acuuid.h>
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME ("ahuuids")
@@ -52,44 +53,36 @@
*/
const AH_UUID AcpiUuids[] =
{
- {"PCI Host Bridge Device",
- "33db4d5b-1ff7-401c-9657-7441c03dd766"},
-
- {"Platform-wide Capabilities",
- "0811b06e-4a27-44f9-8d60-3cbbc22e7b48"},
-
- {"Dynamic Enumeration",
- "d8c1a3a6-be9b-4c9b-91bf-c3cb81fc5daf"},
-
- {"GPIO Controller",
- "4f248f40-d5e2-499f-834c-27758ea1cd3f"},
-
- {"Battery Thermal Limit",
- "4c2067e3-887d-475c-9720-4af1d3ed602e"},
-
- {"Thermal Extensions",
- "14d399cd-7a27-4b18-8fb4-7cb7b9f4e500"},
-
- {"USB Controller",
- "ce2ee385-00e6-48cb-9f05-2edb927c4899"},
-
- {"HID I2C Device",
- "3cdff6f7-4267-4555-ad05-b30a3d8938de"},
-
- {"Power Button Device",
- "dfbcf3c5-e7a5-44e6-9c1f-29c76f6e059c"},
-
- {"Device Labeling Interface",
- "e5c937d0-3553-4d7a-9117-ea4d19c3434d"},
-
- {"SATA Controller",
- "e4db149b-fcfe-425b-a6d8-92357d78fc7f"},
-
- {"Physical Presence Interface",
- "3dddfaa6-361b-4eb4-a424-8d10089d1653"},
-
- {"Device Properties for _DSD",
- "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"},
+ {"[Controllers]", NULL},
+ {"GPIO Controller", UUID_GPIO_CONTROLLER},
+ {"USB Controller", UUID_USB_CONTROLLER},
+ {"SATA Controller", UUID_SATA_CONTROLLER},
+
+ {"[Devices]", NULL},
+ {"PCI Host Bridge Device", UUID_PCI_HOST_BRIDGE},
+ {"HID I2C Device", UUID_I2C_DEVICE},
+ {"Power Button Device", UUID_POWER_BUTTON},
+
+ {"[Interfaces]", NULL},
+ {"Device Labeling Interface", UUID_DEVICE_LABELING},
+ {"Physical Presence Interface", UUID_PHYSICAL_PRESENCE},
+
+ {"[Non-volatile DIMM and NFIT table]", NULL},
+ {"Volatile Memory Region", UUID_VOLATILE_MEMORY},
+ {"Persistent Memory Region", UUID_PERSISTENT_MEMORY},
+ {"NVDIMM Control Region", UUID_CONTROL_REGION},
+ {"NVDIMM Data Region", UUID_DATA_REGION},
+ {"Volatile Virtual Disk", UUID_VOLATILE_VIRTUAL_DISK},
+ {"Volatile Virtual CD", UUID_VOLATILE_VIRTUAL_CD},
+ {"Persistent Virtual Disk", UUID_PERSISTENT_VIRTUAL_DISK},
+ {"Persistent Virtual CD", UUID_PERSISTENT_VIRTUAL_CD},
+
+ {"[Miscellaneous]", NULL},
+ {"Platform-wide Capabilities", UUID_PLATFORM_CAPABILITIES},
+ {"Dynamic Enumeration", UUID_DYNAMIC_ENUMERATION},
+ {"Battery Thermal Limit", UUID_BATTERY_THERMAL_LIMIT},
+ {"Thermal Extensions", UUID_THERMAL_EXTENSIONS},
+ {"Device Properties for _DSD", UUID_DEVICE_PROPERTIES},
{NULL, NULL}
};
@@ -120,6 +113,13 @@ AcpiAhMatchUuid (
for (Info = AcpiUuids; Info->Description; Info++)
{
+ /* Null string means desciption is a UUID class */
+
+ if (!Info->String)
+ {
+ continue;
+ }
+
AcpiUtConvertStringToUuid (Info->String, UuidBuffer);
if (!ACPI_MEMCMP (Data, UuidBuffer, UUID_BUFFER_LENGTH))
diff --git a/sys/contrib/dev/acpica/include/acuuid.h b/sys/contrib/dev/acpica/include/acuuid.h
index cfc4363336ec..59c1768fc7a9 100644
--- a/sys/contrib/dev/acpica/include/acuuid.h
+++ b/sys/contrib/dev/acpica/include/acuuid.h
@@ -50,15 +50,41 @@
* Note2: This file is standalone and should remain that way.
*/
-/* NFIT/NVDIMM */
+/* Controllers */
+
+#define UUID_GPIO_CONTROLLER "4f248f40-d5e2-499f-834c-27758ea1cd3f"
+#define UUID_USB_CONTROLLER "ce2ee385-00e6-48cb-9f05-2edb927c4899"
+#define UUID_SATA_CONTROLLER "e4db149b-fcfe-425b-a6d8-92357d78fc7f"
+
+/* Devices */
+
+#define UUID_PCI_HOST_BRIDGE "33db4d5b-1ff7-401c-9657-7441c03dd766"
+#define UUID_I2C_DEVICE "3cdff6f7-4267-4555-ad05-b30a3d8938de"
+#define UUID_POWER_BUTTON "dfbcf3c5-e7a5-44e6-9c1f-29c76f6e059c"
+
+/* Interfaces */
+
+#define UUID_DEVICE_LABELING "e5c937d0-3553-4d7a-9117-ea4d19c3434d"
+#define UUID_PHYSICAL_PRESENCE "3dddfaa6-361b-4eb4-a424-8d10089d1653"
+
+/* NVDIMM - NFIT table */
+
+#define UUID_VOLATILE_MEMORY "7305944f-fdda-44e3-b16c-3f22d252e5d0"
+#define UUID_PERSISTENT_MEMORY "66f0d379-b4f3-4074-ac43-0d3318b78cdb"
+#define UUID_CONTROL_REGION "92f701f6-13b4-405d-910b-299367e8234c"
+#define UUID_DATA_REGION "91af0530-5d86-470e-a6b0-0a2db9408249"
+#define UUID_VOLATILE_VIRTUAL_DISK "77ab535a-45fc-624b-5560-f7b281d1f96e"
+#define UUID_VOLATILE_VIRTUAL_CD "3d5abd30-4175-87ce-6d64-d2ade523c4bb"
+#define UUID_PERSISTENT_VIRTUAL_DISK "5cea02c9-4d07-69d3-269f-4496fbe096f9"
+#define UUID_PERSISTENT_VIRTUAL_CD "08018188-42cd-bb48-100f-5387d53ded3d"
+
+/* Miscellaneous */
+
+#define UUID_PLATFORM_CAPABILITIES "0811b06e-4a27-44f9-8d60-3cbbc22e7b48"
+#define UUID_DYNAMIC_ENUMERATION "d8c1a3a6-be9b-4c9b-91bf-c3cb81fc5daf"
+#define UUID_BATTERY_THERMAL_LIMIT "4c2067e3-887d-475c-9720-4af1d3ed602e"
+#define UUID_THERMAL_EXTENSIONS "14d399cd-7a27-4b18-8fb4-7cb7b9f4e500"
+#define UUID_DEVICE_PROPERTIES "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"
-#define UUID_VOLATILE_MEMORY "4F940573-DAFD-E344-B16C-3F22D252E5D0"
-#define UUID_PERSISTENT_MEMORY "79D3F066-F3B4-7440-AC43-0D3318B78CDB"
-#define UUID_CONTROL_REGION "F601F792-B413-5D40-910B-299367E8234C"
-#define UUID_DATA_REGION "3005AF91-865D-0E47-A6B0-0A2DB9408249"
-#define UUID_VOLATILE_VIRTUAL_DISK "5A53AB77-FC45-4B62-5560-F7B281D1F96E"
-#define UUID_VOLATILE_VIRTUAL_CD "30BD5A3D-7541-CE87-6D64-D2ADE523C4BB"
-#define UUID_PERSISTENT_VIRTUAL_DISK "C902EA5C-074D-69D3-269F-4496FBE096F9"
-#define UUID_PERSISTENT_VIRTUAL_CD "88810108-CD42-48BB-100F-5387D53DED3D"
#endif /* __AUUID_H__ */
diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c
index c69f8bff2bb1..f8ff1ebca347 100644
--- a/sys/dev/acpi_support/acpi_ibm.c
+++ b/sys/dev/acpi_support/acpi_ibm.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include "opt_acpi.h"
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/bus.h>
#include <machine/cpufunc.h>
@@ -261,6 +262,37 @@ static struct {
{ NULL, 0, NULL, 0 }
};
+/*
+ * Per-model default list of event mask.
+ */
+#define ACPI_IBM_HKEY_RFKILL_MASK (1 << 4)
+#define ACPI_IBM_HKEY_DSWITCH_MASK (1 << 6)
+#define ACPI_IBM_HKEY_BRIGHTNESS_UP_MASK (1 << 15)
+#define ACPI_IBM_HKEY_BRIGHTNESS_DOWN_MASK (1 << 16)
+#define ACPI_IBM_HKEY_SEARCH_MASK (1 << 18)
+#define ACPI_IBM_HKEY_MICMUTE_MASK (1 << 26)
+#define ACPI_IBM_HKEY_SETTINGS_MASK (1 << 28)
+#define ACPI_IBM_HKEY_VIEWOPEN_MASK (1 << 30)
+#define ACPI_IBM_HKEY_VIEWALL_MASK (1 << 31)
+
+struct acpi_ibm_models {
+ const char *maker;
+ const char *product;
+ uint32_t eventmask;
+} acpi_ibm_models[] = {
+ { "LENOVO", "20BSCTO1WW",
+ ACPI_IBM_HKEY_RFKILL_MASK |
+ ACPI_IBM_HKEY_DSWITCH_MASK |
+ ACPI_IBM_HKEY_BRIGHTNESS_UP_MASK |
+ ACPI_IBM_HKEY_BRIGHTNESS_DOWN_MASK |
+ ACPI_IBM_HKEY_SEARCH_MASK |
+ ACPI_IBM_HKEY_MICMUTE_MASK |
+ ACPI_IBM_HKEY_SETTINGS_MASK |
+ ACPI_IBM_HKEY_VIEWOPEN_MASK |
+ ACPI_IBM_HKEY_VIEWALL_MASK
+ }
+};
+
ACPI_SERIAL_DECL(ibm, "ACPI IBM extras");
static int acpi_ibm_probe(device_t dev);
@@ -354,7 +386,9 @@ acpi_ibm_probe(device_t dev)
static int
acpi_ibm_attach(device_t dev)
{
+ int i;
struct acpi_ibm_softc *sc;
+ char *maker, *product;
devclass_t ec_devclass;
ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__);
@@ -445,7 +479,34 @@ acpi_ibm_attach(device_t dev)
/* Hook up light to led(4) */
if (sc->light_set_supported)
- sc->led_dev = led_create_state(ibm_led, sc, "thinklight", sc->light_val);
+ sc->led_dev = led_create_state(ibm_led, sc, "thinklight",
+ (sc->light_val ? 1 : 0));
+
+ /* Enable per-model events. */
+ maker = kern_getenv("smbios.system.maker");
+ product = kern_getenv("smbios.system.product");
+ if (maker != NULL && product != NULL)
+ goto nosmbios;
+
+ for (i = 0; i < nitems(acpi_ibm_models); i++) {
+ if (strcmp(maker, acpi_ibm_models[i].maker) == 0 &&
+ strcmp(product, acpi_ibm_models[i].product) == 0) {
+ ACPI_SERIAL_BEGIN(ibm);
+ acpi_ibm_sysctl_set(sc, ACPI_IBM_METHOD_EVENTMASK,
+ acpi_ibm_models[i].eventmask);
+ ACPI_SERIAL_END(ibm);
+ }
+ }
+
+nosmbios:
+ freeenv(maker);
+ freeenv(product);
+
+ /* Enable events by default. */
+ ACPI_SERIAL_BEGIN(ibm);
+ acpi_ibm_sysctl_set(sc, ACPI_IBM_METHOD_EVENTS, 1);
+ ACPI_SERIAL_END(ibm);
+
return (0);
}
@@ -769,7 +830,6 @@ acpi_ibm_sysctl_init(struct acpi_ibm_softc *sc, int method)
switch (method) {
case ACPI_IBM_METHOD_EVENTS:
- /* Events are disabled by default */
return (TRUE);
case ACPI_IBM_METHOD_EVENTMASK:
@@ -1228,7 +1288,6 @@ acpi_ibm_notify(ACPI_HANDLE h, UINT32 notify, void *context)
for (;;) {
acpi_GetInteger(acpi_get_handle(dev), IBM_NAME_EVENTS_GET, &event);
-
if (event == 0)
break;
diff --git a/sys/dev/acpica/Osd/OsdHardware.c b/sys/dev/acpica/Osd/OsdHardware.c
index 1761670da576..8d94e7bc6945 100644
--- a/sys/dev/acpica/Osd/OsdHardware.c
+++ b/sys/dev/acpica/Osd/OsdHardware.c
@@ -89,6 +89,10 @@ AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value,
UINT32 Width)
{
+#ifdef __aarch64__
+ /* ARM64TODO: Add pci support */
+ return (AE_SUPPORT);
+#else
if (Width == 64)
return (AE_SUPPORT);
@@ -99,6 +103,7 @@ AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value,
PciId->Function, Register, Width / 8);
return (AE_OK);
+#endif
}
@@ -107,6 +112,10 @@ AcpiOsWritePciConfiguration (ACPI_PCI_ID *PciId, UINT32 Register,
UINT64 Value, UINT32 Width)
{
+#ifdef __aarch64__
+ /* ARM64TODO: Add pci support */
+ return (AE_SUPPORT);
+#else
if (Width == 64)
return (AE_SUPPORT);
@@ -117,4 +126,5 @@ AcpiOsWritePciConfiguration (ACPI_PCI_ID *PciId, UINT32 Register,
Value, Width / 8);
return (AE_OK);
+#endif
}
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c
index 21fccca29fd7..e3269db7b7aa 100644
--- a/sys/dev/acpica/acpi_cpu.c
+++ b/sys/dev/acpica/acpi_cpu.c
@@ -183,7 +183,9 @@ static int acpi_cpu_cx_cst(struct acpi_cpu_softc *sc);
static void acpi_cpu_startup(void *arg);
static void acpi_cpu_startup_cx(struct acpi_cpu_softc *sc);
static void acpi_cpu_cx_list(struct acpi_cpu_softc *sc);
+#if defined(__i386__) || defined(__amd64__)
static void acpi_cpu_idle(sbintime_t sbt);
+#endif
static void acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context);
static void acpi_cpu_quirks(void);
static void acpi_cpu_quirks_piix4(void);
@@ -475,12 +477,14 @@ enable_idle(struct acpi_cpu_softc *sc)
sc->cpu_disable_idle = FALSE;
}
+#if defined(__i386__) || defined(__amd64__)
static int
is_idle_disabled(struct acpi_cpu_softc *sc)
{
return (sc->cpu_disable_idle);
}
+#endif
/*
* Disable any entry to the idle function during suspend and re-enable it
@@ -999,7 +1003,9 @@ acpi_cpu_startup(void *arg)
sc = device_get_softc(cpu_devices[i]);
enable_idle(sc);
}
+#if defined(__i386__) || defined(__amd64__)
cpu_idle_hook = acpi_cpu_idle;
+#endif
}
static void
@@ -1061,6 +1067,7 @@ acpi_cpu_startup_cx(struct acpi_cpu_softc *sc)
}
}
+#if defined(__i386__) || defined(__amd64__)
/*
* Idle the CPU in the lowest state possible. This function is called with
* interrupts disabled. Note that once it re-enables interrupts, a task
@@ -1074,6 +1081,7 @@ acpi_cpu_idle(sbintime_t sbt)
struct acpi_cx *cx_next;
uint64_t cputicks;
uint32_t start_time, end_time;
+ ACPI_STATUS status;
int bm_active, cx_next_idx, i, us;
/*
@@ -1119,8 +1127,8 @@ acpi_cpu_idle(sbintime_t sbt)
*/
if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0 &&
cx_next_idx > sc->cpu_non_c3) {
- AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_STATUS, &bm_active);
- if (bm_active != 0) {
+ status = AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_STATUS, &bm_active);
+ if (ACPI_SUCCESS(status) && bm_active != 0) {
AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_STATUS, 1);
cx_next_idx = sc->cpu_non_c3;
}
@@ -1207,6 +1215,7 @@ acpi_cpu_idle(sbintime_t sbt)
sc->cpu_prev_sleep = (sc->cpu_prev_sleep * 3 + PM_USEC(end_time)) / 4;
}
+#endif
/*
* Re-evaluate the _CST object when we are notified that it changed.
@@ -1285,6 +1294,7 @@ acpi_cpu_quirks_piix4(void)
#ifdef __i386__
device_t acpi_dev;
uint32_t val;
+ ACPI_STATUS status;
acpi_dev = pci_find_device(PCI_VENDOR_INTEL, PCI_DEVICE_82371AB_3);
if (acpi_dev != NULL) {
@@ -1323,8 +1333,8 @@ acpi_cpu_quirks_piix4(void)
val |= PIIX4_STOP_BREAK_MASK;
pci_write_config(acpi_dev, PIIX4_DEVACTB_REG, val, 4);
}
- AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_RLD, &val);
- if (val) {
+ status = AcpiReadBitRegister(ACPI_BITREG_BUS_MASTER_RLD, &val);
+ if (ACPI_SUCCESS(status) && val != 0) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"acpi_cpu: PIIX4: reset BRLD_EN_BM\n"));
AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 0);
diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h
index 33de2f9353c0..68925273b445 100644
--- a/sys/dev/ahci/ahci.h
+++ b/sys/dev/ahci/ahci.h
@@ -578,7 +578,7 @@ enum ahci_err_type {
#define AHCI_Q_RESTORE_CAP 0x00080000
#define AHCI_Q_BIT_STRING \
- "\021" \
+ "\020" \
"\001NOFORCE" \
"\002NOPMP" \
"\003NONCQ" \
diff --git a/sys/dev/aic7xxx/aic79xx_pci.c b/sys/dev/aic7xxx/aic79xx_pci.c
index cb2dbc31b42b..0b8ca400441a 100644
--- a/sys/dev/aic7xxx/aic79xx_pci.c
+++ b/sys/dev/aic7xxx/aic79xx_pci.c
@@ -93,6 +93,11 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
#define ID_AIC7902_PCI_REV_A4 0x3
#define ID_AIC7902_PCI_REV_B0 0x10
#define SUBID_HP 0x0E11
+#define DEVICE8081 0x8081
+#define DEVICE8088 0x8088
+#define DEVICE8089 0x8089
+#define ADAPTECVENDORID 0x9005
+#define SUBVENDOR9005 0x9005
#define DEVID_9005_HOSTRAID(id) ((id) & 0x80)
@@ -292,6 +297,15 @@ ahd_find_pci_device(aic_dev_softc_t pci)
device = aic_pci_read_config(pci, PCIR_DEVICE, /*bytes*/2);
subvendor = aic_pci_read_config(pci, PCIR_SUBVEND_0, /*bytes*/2);
subdevice = aic_pci_read_config(pci, PCIR_SUBDEV_0, /*bytes*/2);
+
+ if ((vendor == ADAPTECVENDORID) && (subvendor == SUBVENDOR9005)) {
+ if ((device == DEVICE8081) || (device == DEVICE8088) ||
+ (device == DEVICE8089)) {
+ printf("Controller device ID conflict with PMC Adaptec HBA\n");
+ return (NULL);
+ }
+ }
+
full_id = ahd_compose_id(device,
vendor,
subdevice,
diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c
index 36cd679bc0ba..3606e14c28c3 100644
--- a/sys/dev/ath/ath_rate/sample/sample.c
+++ b/sys/dev/ath/ath_rate/sample/sample.c
@@ -843,9 +843,11 @@ update_stats(struct ath_softc *sc, struct ath_node *an,
}
static void
-badrate(struct ifnet *ifp, int series, int hwrate, int tries, int status)
+badrate(struct ath_softc *sc, int series, int hwrate, int tries, int status)
{
- if_printf(ifp, "bad series%d hwrate 0x%x, tries %u ts_status 0x%x\n",
+
+ device_printf(sc->sc_dev,
+ "bad series%d hwrate 0x%x, tries %u ts_status 0x%x\n",
series, hwrate, tries, status);
}
@@ -891,9 +893,10 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
if (!mrr || ts->ts_finaltsi == 0) {
if (!IS_RATE_DEFINED(sn, final_rix)) {
- device_printf(sc->sc_dev, "%s: ts_rate=%d ts_finaltsi=%d, final_rix=%d\n",
+ device_printf(sc->sc_dev,
+ "%s: ts_rate=%d ts_finaltsi=%d, final_rix=%d\n",
__func__, ts->ts_rate, ts->ts_finaltsi, final_rix);
- badrate(ifp, 0, ts->ts_rate, long_tries, status);
+ badrate(sc, 0, ts->ts_rate, long_tries, status);
return;
}
/*
@@ -945,7 +948,7 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
for (i = 0; i < 4; i++) {
if (rc[i].tries && !IS_RATE_DEFINED(sn, rc[i].rix))
- badrate(ifp, 0, rc[i].ratecode, rc[i].tries,
+ badrate(sc, 0, rc[i].ratecode, rc[i].tries,
status);
}
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 83d9bd2966ed..4aac93bb0f5b 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -166,9 +166,9 @@ static void ath_bmiss_proc(void *, int);
static void ath_key_update_begin(struct ieee80211vap *);
static void ath_key_update_end(struct ieee80211vap *);
static void ath_update_mcast_hw(struct ath_softc *);
-static void ath_update_mcast(struct ifnet *);
-static void ath_update_promisc(struct ifnet *);
-static void ath_updateslot(struct ifnet *);
+static void ath_update_mcast(struct ieee80211com *);
+static void ath_update_promisc(struct ieee80211com *);
+static void ath_updateslot(struct ieee80211com *);
static void ath_bstuck_proc(void *, int);
static void ath_reset_proc(void *, int);
static int ath_desc_alloc(struct ath_softc *);
@@ -592,8 +592,9 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
goto bad;
}
ic = ifp->if_l2com;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(sc->sc_dev);
- /* set these up early for if_printf use */
if_initname(ifp, device_get_name(sc->sc_dev),
device_get_unit(sc->sc_dev));
CURVNET_RESTORE();
@@ -610,8 +611,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
ah = ath_hal_attach(devid, sc, sc->sc_st, sc->sc_sh,
sc->sc_eepromdata, &ah_config, &status);
if (ah == NULL) {
- if_printf(ifp, "unable to attach hardware; HAL status %u\n",
- status);
+ device_printf(sc->sc_dev,
+ "unable to attach hardware; HAL status %u\n", status);
error = ENXIO;
goto bad;
}
@@ -662,8 +663,9 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
*/
sc->sc_keymax = ath_hal_keycachesize(ah);
if (sc->sc_keymax > ATH_KEYMAX) {
- if_printf(ifp, "Warning, using only %u of %u key cache slots\n",
- ATH_KEYMAX, sc->sc_keymax);
+ device_printf(sc->sc_dev,
+ "Warning, using only %u of %u key cache slots\n",
+ ATH_KEYMAX, sc->sc_keymax);
sc->sc_keymax = ATH_KEYMAX;
}
/*
@@ -702,14 +704,14 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
*/
error = ath_desc_alloc(sc);
if (error != 0) {
- if_printf(ifp, "failed to allocate TX descriptors: %d\n",
- error);
+ device_printf(sc->sc_dev,
+ "failed to allocate TX descriptors: %d\n", error);
goto bad;
}
error = ath_txdma_setup(sc);
if (error != 0) {
- if_printf(ifp, "failed to allocate TX descriptors: %d\n",
- error);
+ device_printf(sc->sc_dev,
+ "failed to allocate TX descriptors: %d\n", error);
goto bad;
}
@@ -718,8 +720,8 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
*/
error = ath_rxdma_setup(sc);
if (error != 0) {
- if_printf(ifp, "failed to allocate RX descriptors: %d\n",
- error);
+ device_printf(sc->sc_dev,
+ "failed to allocate RX descriptors: %d\n", error);
goto bad;
}
@@ -750,20 +752,22 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
*/
sc->sc_bhalq = ath_beaconq_setup(sc);
if (sc->sc_bhalq == (u_int) -1) {
- if_printf(ifp, "unable to setup a beacon xmit queue!\n");
+ device_printf(sc->sc_dev,
+ "unable to setup a beacon xmit queue!\n");
error = EIO;
goto bad2;
}
sc->sc_cabq = ath_txq_setup(sc, HAL_TX_QUEUE_CAB, 0);
if (sc->sc_cabq == NULL) {
- if_printf(ifp, "unable to setup CAB xmit queue!\n");
+ device_printf(sc->sc_dev, "unable to setup CAB xmit queue!\n");
error = EIO;
goto bad2;
}
/* NB: insure BK queue is the lowest priority h/w queue */
if (!ath_tx_setup(sc, WME_AC_BK, HAL_WME_AC_BK)) {
- if_printf(ifp, "unable to setup xmit queue for %s traffic!\n",
- ieee80211_wme_acnames[WME_AC_BK]);
+ device_printf(sc->sc_dev,
+ "unable to setup xmit queue for %s traffic!\n",
+ ieee80211_wme_acnames[WME_AC_BK]);
error = EIO;
goto bad2;
}
@@ -1826,8 +1830,8 @@ ath_vap_delete(struct ieee80211vap *vap)
* be reset if we just destroyed the last vap).
*/
if (ath_startrecv(sc) != 0)
- if_printf(ifp, "%s: unable to restart recv logic\n",
- __func__);
+ device_printf(sc->sc_dev,
+ "%s: unable to restart recv logic\n", __func__);
if (sc->sc_beacons) { /* restart beacons */
#ifdef IEEE80211_SUPPORT_TDMA
if (sc->sc_tdma)
@@ -2314,7 +2318,7 @@ ath_fatal_proc(void *arg, int pending)
u_int32_t len;
void *sp;
- if_printf(ifp, "hardware error; resetting\n");
+ device_printf(sc->sc_dev, "hardware error; resetting\n");
/*
* Fatal errors are unrecoverable. Typically these
* are caused by DMA errors. Collect h/w state from
@@ -2323,9 +2327,9 @@ ath_fatal_proc(void *arg, int pending)
if (ath_hal_getfatalstate(sc->sc_ah, &sp, &len)) {
KASSERT(len >= 6*sizeof(u_int32_t), ("len %u bytes", len));
state = sp;
- if_printf(ifp, "0x%08x 0x%08x 0x%08x, 0x%08x 0x%08x 0x%08x\n",
- state[0], state[1] , state[2], state[3],
- state[4], state[5]);
+ device_printf(sc->sc_dev,
+ "0x%08x 0x%08x 0x%08x, 0x%08x 0x%08x 0x%08x\n", state[0],
+ state[1] , state[2], state[3], state[4], state[5]);
}
ath_reset(ifp, ATH_RESET_NOLOSS);
}
@@ -2432,7 +2436,8 @@ ath_bmiss_proc(void *arg, int pending)
*/
if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0) {
ath_reset(ifp, ATH_RESET_NOLOSS);
- if_printf(ifp, "bb hang detected (0x%x), resetting\n", hangs);
+ device_printf(sc->sc_dev,
+ "bb hang detected (0x%x), resetting\n", hangs);
} else {
ath_reset(ifp, ATH_RESET_NOLOSS);
ieee80211_beacon_miss(ifp->if_l2com);
@@ -2507,9 +2512,10 @@ ath_init(void *arg)
ath_hal_setchainmasks(sc->sc_ah, sc->sc_cur_txchainmask,
sc->sc_cur_rxchainmask);
- if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_FALSE, &status)) {
- if_printf(ifp, "unable to reset hardware; hal status %u\n",
- status);
+ if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_FALSE,
+ &status)) {
+ device_printf(sc->sc_dev,
+ "unable to reset hardware; hal status %u\n", status);
ATH_UNLOCK(sc);
return;
}
@@ -2567,7 +2573,7 @@ ath_init(void *arg)
* here except setup the interrupt mask.
*/
if (ath_startrecv(sc) != 0) {
- if_printf(ifp, "unable to start recv logic\n");
+ device_printf(sc->sc_dev, "unable to start recv logic\n");
ath_power_restore_power_state(sc);
ATH_UNLOCK(sc);
return;
@@ -2909,8 +2915,9 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
ath_hal_setchainmasks(sc->sc_ah, sc->sc_cur_txchainmask,
sc->sc_cur_rxchainmask);
if (!ath_hal_reset(ah, sc->sc_opmode, ic->ic_curchan, AH_TRUE, &status))
- if_printf(ifp, "%s: unable to reset hardware; hal status %u\n",
- __func__, status);
+ device_printf(sc->sc_dev,
+ "%s: unable to reset hardware; hal status %u\n",
+ __func__, status);
sc->sc_diversity = ath_hal_getdiversity(ah);
ATH_RX_LOCK(sc);
@@ -2939,7 +2946,8 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
ath_hal_setenforcetxop(sc->sc_ah, 0);
if (ath_startrecv(sc) != 0) /* restart recv */
- if_printf(ifp, "%s: unable to start recv logic\n", __func__);
+ device_printf(sc->sc_dev,
+ "%s: unable to start recv logic\n", __func__);
/*
* We may be doing a reset in response to an ioctl
* that changes the channel so update any state that
@@ -3545,9 +3553,9 @@ ath_key_update_end(struct ieee80211vap *vap)
}
static void
-ath_update_promisc(struct ifnet *ifp)
+ath_update_promisc(struct ieee80211com *ic)
{
- struct ath_softc *sc = ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
u_int32_t rfilt;
/* configure rx filter */
@@ -3609,9 +3617,9 @@ ath_update_mcast_hw(struct ath_softc *sc)
* awake before operating.
*/
static void
-ath_update_mcast(struct ifnet *ifp)
+ath_update_mcast(struct ieee80211com *ic)
{
- struct ath_softc *sc = ifp->if_softc;
+ struct ath_softc *sc = ic->ic_softc;
ATH_LOCK(sc);
ath_power_set_power_state(sc, HAL_PM_AWAKE);
@@ -3695,10 +3703,9 @@ ath_setslottime(struct ath_softc *sc)
* slot time based on the current setting.
*/
static void
-ath_updateslot(struct ifnet *ifp)
+ath_updateslot(struct ieee80211com *ic)
{
- struct ath_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ath_softc *sc = ic->ic_softc;
/*
* When not coordinating the BSS, change the hardware
@@ -3746,7 +3753,7 @@ ath_reset_proc(void *arg, int pending)
struct ifnet *ifp = sc->sc_ifp;
#if 0
- if_printf(ifp, "%s: resetting\n", __func__);
+ device_printf(sc->sc_dev, "%s: resetting\n", __func__);
#endif
ath_reset(ifp, ATH_RESET_NOLOSS);
}
@@ -3762,15 +3769,15 @@ ath_bstuck_proc(void *arg, int pending)
uint32_t hangs = 0;
if (ath_hal_gethangstate(sc->sc_ah, 0xff, &hangs) && hangs != 0)
- if_printf(ifp, "bb hang detected (0x%x)\n", hangs);
+ device_printf(sc->sc_dev, "bb hang detected (0x%x)\n", hangs);
#ifdef ATH_DEBUG_ALQ
if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_STUCK_BEACON))
if_ath_alq_post(&sc->sc_alq, ATH_ALQ_STUCK_BEACON, 0, NULL);
#endif
- if_printf(ifp, "stuck beacon; resetting (bmiss count %u)\n",
- sc->sc_bmisscount);
+ device_printf(sc->sc_dev, "stuck beacon; resetting (bmiss count %u)\n",
+ sc->sc_bmisscount);
sc->sc_stats.ast_bstuck++;
/*
* This assumes that there's no simultaneous channel mode change
@@ -3802,7 +3809,6 @@ ath_descdma_alloc_desc(struct ath_softc *sc,
((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
#define ATH_DESC_4KB_BOUND_CHECK(_daddr, _len) \
((((u_int32_t)(_daddr) & 0xFFF) > (0x1000 - (_len))) ? 1 : 0)
- struct ifnet *ifp = sc->sc_ifp;
int error;
dd->dd_descsize = ds_size;
@@ -3843,7 +3849,8 @@ ath_descdma_alloc_desc(struct ath_softc *sc,
NULL, /* lockarg */
&dd->dd_dmat);
if (error != 0) {
- if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name);
+ device_printf(sc->sc_dev,
+ "cannot allocate %s DMA tag\n", dd->dd_name);
return error;
}
@@ -3852,8 +3859,9 @@ ath_descdma_alloc_desc(struct ath_softc *sc,
BUS_DMA_NOWAIT | BUS_DMA_COHERENT,
&dd->dd_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to alloc memory for %u %s descriptors, "
- "error %u\n", ndesc, dd->dd_name, error);
+ device_printf(sc->sc_dev,
+ "unable to alloc memory for %u %s descriptors, error %u\n",
+ ndesc, dd->dd_name, error);
goto fail1;
}
@@ -3862,8 +3870,9 @@ ath_descdma_alloc_desc(struct ath_softc *sc,
ath_load_cb, &dd->dd_desc_paddr,
BUS_DMA_NOWAIT);
if (error != 0) {
- if_printf(ifp, "unable to map %s descriptors, error %u\n",
- dd->dd_name, error);
+ device_printf(sc->sc_dev,
+ "unable to map %s descriptors, error %u\n",
+ dd->dd_name, error);
goto fail2;
}
@@ -3893,7 +3902,6 @@ ath_descdma_setup(struct ath_softc *sc,
((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
#define ATH_DESC_4KB_BOUND_CHECK(_daddr, _len) \
((((u_int32_t)(_daddr) & 0xFFF) > (0x1000 - (_len))) ? 1 : 0)
- struct ifnet *ifp = sc->sc_ifp;
uint8_t *ds;
struct ath_buf *bf;
int i, bsize, error;
@@ -3913,8 +3921,9 @@ ath_descdma_setup(struct ath_softc *sc,
bsize = sizeof(struct ath_buf) * nbuf;
bf = malloc(bsize, M_ATHDEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
- if_printf(ifp, "malloc of %s buffers failed, size %u\n",
- dd->dd_name, bsize);
+ device_printf(sc->sc_dev,
+ "malloc of %s buffers failed, size %u\n",
+ dd->dd_name, bsize);
goto fail3;
}
dd->dd_bufptr = bf;
@@ -3940,8 +3949,9 @@ ath_descdma_setup(struct ath_softc *sc,
error = bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT,
&bf->bf_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to create dmamap for %s "
- "buffer %u, error %u\n", dd->dd_name, i, error);
+ device_printf(sc->sc_dev, "unable to create dmamap "
+ "for %s buffer %u, error %u\n",
+ dd->dd_name, i, error);
ath_descdma_cleanup(sc, dd, head);
return error;
}
@@ -3977,7 +3987,6 @@ ath_descdma_setup_rx_edma(struct ath_softc *sc,
struct ath_descdma *dd, ath_bufhead *head,
const char *name, int nbuf, int rx_status_len)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ath_buf *bf;
int i, bsize, error;
@@ -4000,8 +4009,9 @@ ath_descdma_setup_rx_edma(struct ath_softc *sc,
bsize = sizeof(struct ath_buf) * nbuf;
bf = malloc(bsize, M_ATHDEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
- if_printf(ifp, "malloc of %s buffers failed, size %u\n",
- dd->dd_name, bsize);
+ device_printf(sc->sc_dev,
+ "malloc of %s buffers failed, size %u\n",
+ dd->dd_name, bsize);
error = ENOMEM;
goto fail3;
}
@@ -4016,8 +4026,9 @@ ath_descdma_setup_rx_edma(struct ath_softc *sc,
error = bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT,
&bf->bf_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to create dmamap for %s "
- "buffer %u, error %u\n", dd->dd_name, i, error);
+ device_printf(sc->sc_dev, "unable to create dmamap "
+ "for %s buffer %u, error %u\n",
+ dd->dd_name, i, error);
ath_descdma_cleanup(sc, dd, head);
return error;
}
@@ -4391,9 +4402,8 @@ ath_txq_update(struct ath_softc *sc, int ac)
qi.tqi_aifs, qi.tqi_cwmin, qi.tqi_cwmax, qi.tqi_burstTime);
if (!ath_hal_settxqueueprops(ah, txq->axq_qnum, &qi)) {
- if_printf(ifp, "unable to update hardware queue "
- "parameters for %s traffic!\n",
- ieee80211_wme_acnames[ac]);
+ device_printf(sc->sc_dev, "unable to update hardware queue "
+ "parameters for %s traffic!\n", ieee80211_wme_acnames[ac]);
return 0;
} else {
ath_hal_resettxqueue(ah, txq->axq_qnum); /* push to h/w */
@@ -5559,7 +5569,7 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
ath_hal_setchainmasks(sc->sc_ah, sc->sc_cur_txchainmask,
sc->sc_cur_rxchainmask);
if (!ath_hal_reset(ah, sc->sc_opmode, chan, AH_TRUE, &status)) {
- if_printf(ifp, "%s: unable to reset "
+ device_printf(sc->sc_dev, "%s: unable to reset "
"channel %u (%u MHz, flags 0x%x), hal status %u\n",
__func__, ieee80211_chan2ieee(ic, chan),
chan->ic_freq, chan->ic_flags, status);
@@ -5598,8 +5608,8 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
* Re-enable rx framework.
*/
if (ath_startrecv(sc) != 0) {
- if_printf(ifp, "%s: unable to restart recv logic\n",
- __func__);
+ device_printf(sc->sc_dev,
+ "%s: unable to restart recv logic\n", __func__);
ret = EIO;
goto finish;
}
@@ -6374,8 +6384,9 @@ ath_getchannels(struct ath_softc *sc)
status = ath_hal_init_channels(ah, ic->ic_channels, IEEE80211_CHAN_MAX,
&ic->ic_nchans, HAL_MODE_ALL, CTRY_DEFAULT, SKU_NONE, AH_TRUE);
if (status != HAL_OK) {
- if_printf(ifp, "%s: unable to collect channel list from hal, "
- "status %d\n", __func__, status);
+ device_printf(sc->sc_dev,
+ "%s: unable to collect channel list from hal, status %d\n",
+ __func__, status);
return EINVAL;
}
(void) ath_hal_getregdomain(ah, &sc->sc_eerd);
@@ -6537,10 +6548,10 @@ ath_watchdog(void *arg)
if (ath_hal_gethangstate(sc->sc_ah, 0xffff, &hangs) &&
hangs != 0) {
- if_printf(ifp, "%s hang detected (0x%x)\n",
+ device_printf(sc->sc_dev, "%s hang detected (0x%x)\n",
hangs & 0xff ? "bb" : "mac", hangs);
} else
- if_printf(ifp, "device timeout\n");
+ device_printf(sc->sc_dev, "device timeout\n");
do_reset = 1;
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
sc->sc_stats.ast_watchdog++;
@@ -6785,31 +6796,32 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
static void
ath_announce(struct ath_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ath_hal *ah = sc->sc_ah;
- if_printf(ifp, "AR%s mac %d.%d RF%s phy %d.%d\n",
+ device_printf(sc->sc_dev, "AR%s mac %d.%d RF%s phy %d.%d\n",
ath_hal_mac_name(ah), ah->ah_macVersion, ah->ah_macRev,
ath_hal_rf_name(ah), ah->ah_phyRev >> 4, ah->ah_phyRev & 0xf);
- if_printf(ifp, "2GHz radio: 0x%.4x; 5GHz radio: 0x%.4x\n",
+ device_printf(sc->sc_dev, "2GHz radio: 0x%.4x; 5GHz radio: 0x%.4x\n",
ah->ah_analog2GhzRev, ah->ah_analog5GhzRev);
if (bootverbose) {
int i;
for (i = 0; i <= WME_AC_VO; i++) {
struct ath_txq *txq = sc->sc_ac2q[i];
- if_printf(ifp, "Use hw queue %u for %s traffic\n",
- txq->axq_qnum, ieee80211_wme_acnames[i]);
+ device_printf(sc->sc_dev,
+ "Use hw queue %u for %s traffic\n",
+ txq->axq_qnum, ieee80211_wme_acnames[i]);
}
- if_printf(ifp, "Use hw queue %u for CAB traffic\n",
- sc->sc_cabq->axq_qnum);
- if_printf(ifp, "Use hw queue %u for beacons\n", sc->sc_bhalq);
+ device_printf(sc->sc_dev, "Use hw queue %u for CAB traffic\n",
+ sc->sc_cabq->axq_qnum);
+ device_printf(sc->sc_dev, "Use hw queue %u for beacons\n",
+ sc->sc_bhalq);
}
if (ath_rxbuf != ATH_RXBUF)
- if_printf(ifp, "using %u rx buffers\n", ath_rxbuf);
+ device_printf(sc->sc_dev, "using %u rx buffers\n", ath_rxbuf);
if (ath_txbuf != ATH_TXBUF)
- if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
+ device_printf(sc->sc_dev, "using %u tx buffers\n", ath_txbuf);
if (sc->sc_mcastkey && bootverbose)
- if_printf(ifp, "using multicast key search\n");
+ device_printf(sc->sc_dev, "using multicast key search\n");
}
static void
diff --git a/sys/dev/ath/if_ath_rx.c b/sys/dev/ath/if_ath_rx.c
index bed94887c988..2779b7a59053 100644
--- a/sys/dev/ath/if_ath_rx.c
+++ b/sys/dev/ath/if_ath_rx.c
@@ -327,7 +327,7 @@ ath_legacy_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
*/
void
ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc;
@@ -353,7 +353,7 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
* Call up first so subsequent work can use information
* potentially stored in the node (e.g. for ibss merge).
*/
- ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, nf);
+ ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BEACON:
/* update rssi statistics for use by the hal */
@@ -1037,7 +1037,7 @@ ath_rx_proc(struct ath_softc *sc, int resched)
bf = TAILQ_FIRST(&sc->sc_rxbuf);
if (sc->sc_rxslink && bf == NULL) { /* NB: shouldn't happen */
- if_printf(ifp, "%s: no buffer!\n", __func__);
+ device_printf(sc->sc_dev, "%s: no buffer!\n", __func__);
break;
} else if (bf == NULL) {
/*
@@ -1054,7 +1054,7 @@ ath_rx_proc(struct ath_softc *sc, int resched)
* will be no mbuf; try again to re-populate it.
*/
/* XXX make debug msg */
- if_printf(ifp, "%s: no mbuf!\n", __func__);
+ device_printf(sc->sc_dev, "%s: no mbuf!\n", __func__);
TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list);
goto rx_proc_next;
}
diff --git a/sys/dev/ath/if_ath_rx.h b/sys/dev/ath/if_ath_rx.h
index f831148bfd25..62be699f752b 100644
--- a/sys/dev/ath/if_ath_rx.h
+++ b/sys/dev/ath/if_ath_rx.h
@@ -33,7 +33,8 @@
extern u_int32_t ath_calcrxfilter(struct ath_softc *sc);
extern void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
- int subtype, int rssi, int nf);
+ int subtype, const struct ieee80211_rx_stats *rxs,
+ int rssi, int nf);
#define ath_stoprecv(_sc, _dodelay) \
(_sc)->sc_rx.recv_stop((_sc), (_dodelay))
diff --git a/sys/dev/ath/if_ath_tdma.c b/sys/dev/ath/if_ath_tdma.c
index de1a91ca02e9..fd23db1977da 100644
--- a/sys/dev/ath/if_ath_tdma.c
+++ b/sys/dev/ath/if_ath_tdma.c
@@ -259,7 +259,7 @@ ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap)
if (vap == NULL) {
vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */
if (vap == NULL) {
- if_printf(ifp, "%s: no vaps?\n", __func__);
+ device_printf(sc->sc_dev, "%s: no vaps?\n", __func__);
return;
}
}
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c
index 096278eb4519..c15b1583761a 100644
--- a/sys/dev/ath/if_ath_tx.c
+++ b/sys/dev/ath/if_ath_tx.c
@@ -1691,8 +1691,8 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
flags |= HAL_TXDESC_NOACK;
break;
default:
- if_printf(ifp, "bogus frame type 0x%x (%s)\n",
- wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
+ device_printf(sc->sc_dev, "bogus frame type 0x%x (%s)\n",
+ wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
/* XXX statistic */
/* XXX free tx dmamap */
ath_freetx(m0);
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index e888ca2ee9ed..5c5e6cd3d287 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -481,7 +481,8 @@ struct ath_vap {
struct ath_txq av_mcastq; /* buffered mcast s/w queue */
void (*av_recv_mgmt)(struct ieee80211_node *,
- struct mbuf *, int, int, int);
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *, int, int);
int (*av_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
void (*av_bmiss)(struct ieee80211vap *);
diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c
index 7f3f97d8e295..7ef32a4e58fe 100644
--- a/sys/dev/atkbdc/psm.c
+++ b/sys/dev/atkbdc/psm.c
@@ -462,7 +462,8 @@ static int tame_mouse(struct psm_softc *, packetbuf_t *, mousestatus_t *,
u_char *);
/* vendor specific features */
-typedef int probefunc_t(KBDC, struct psm_softc *);
+enum probearg { PROBE, REINIT };
+typedef int probefunc_t(struct psm_softc *, enum probearg);
static int mouse_id_proc1(KBDC, int, int, int *);
static int mouse_ext_command(KBDC, int);
@@ -882,7 +883,7 @@ doinitialize(struct psm_softc *sc, mousemode_t *mode)
/* Re-enable the mouse. */
for (i = 0; vendortype[i].probefunc != NULL; ++i)
if (vendortype[i].model == sc->hw.model)
- (*vendortype[i].probefunc)(sc->kbdc, NULL);
+ (*vendortype[i].probefunc)(sc, REINIT);
/* set mouse parameters */
if (mode != (mousemode_t *)NULL) {
@@ -893,13 +894,6 @@ doinitialize(struct psm_softc *sc, mousemode_t *mode)
set_mouse_resolution(kbdc, mode->resolution);
set_mouse_scaling(kbdc, 1);
set_mouse_mode(kbdc);
-
- /*
- * Trackpoint settings are lost on resume.
- * Restore them here.
- */
- if (sc->tphw > 0)
- set_trackpoint_parameters(sc);
}
/* Record sync on the next data packet we see. */
@@ -1388,7 +1382,7 @@ psmprobe(device_t dev)
/* other parameters */
for (i = 0; vendortype[i].probefunc != NULL; ++i)
- if ((*vendortype[i].probefunc)(sc->kbdc, sc)) {
+ if ((*vendortype[i].probefunc)(sc, PROBE)) {
if (verbose >= 2)
printf("psm%d: found %s\n", unit,
model_name(vendortype[i].model));
@@ -3731,8 +3725,9 @@ mouse_ext_command(KBDC kbdc, int command)
#ifdef notyet
/* Logitech MouseMan Cordless II */
static int
-enable_lcordless(KDBC kbdc, struct psm_softc *sc)
+enable_lcordless(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int status[3];
int ch;
@@ -3753,8 +3748,9 @@ enable_lcordless(KDBC kbdc, struct psm_softc *sc)
/* Genius NetScroll Mouse, MouseSystems SmartScroll Mouse */
static int
-enable_groller(KBDC kbdc, struct psm_softc *sc)
+enable_groller(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int status[3];
/*
@@ -3783,15 +3779,16 @@ enable_groller(KBDC kbdc, struct psm_softc *sc)
if ((status[1] != '3') || (status[2] != 'D'))
return (FALSE);
/* FIXME: SmartScroll Mouse has 5 buttons! XXX */
- if (sc != NULL)
+ if (arg == PROBE)
sc->hw.buttons = 4;
return (TRUE);
}
/* Genius NetMouse/NetMouse Pro, ASCII Mie Mouse, NetScroll Optical */
static int
-enable_gmouse(KBDC kbdc, struct psm_softc *sc)
+enable_gmouse(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int status[3];
/*
@@ -3813,8 +3810,9 @@ enable_gmouse(KBDC kbdc, struct psm_softc *sc)
/* ALPS GlidePoint */
static int
-enable_aglide(KBDC kbdc, struct psm_softc *sc)
+enable_aglide(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int status[3];
/*
@@ -3835,9 +3833,10 @@ enable_aglide(KBDC kbdc, struct psm_softc *sc)
/* Kensington ThinkingMouse/Trackball */
static int
-enable_kmouse(KBDC kbdc, struct psm_softc *sc)
+enable_kmouse(struct psm_softc *sc, enum probearg arg)
{
static u_char rate[] = { 20, 60, 40, 20, 20, 60, 40, 20, 20 };
+ KBDC kbdc = sc->kbdc;
int status[3];
int id1;
int id2;
@@ -3888,8 +3887,9 @@ enable_kmouse(KBDC kbdc, struct psm_softc *sc)
/* Logitech MouseMan+/FirstMouse+, IBM ScrollPoint Mouse */
static int
-enable_mmanplus(KBDC kbdc, struct psm_softc *sc)
+enable_mmanplus(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int data[3];
/* the special sequence to enable the fourth button and the roller. */
@@ -3930,7 +3930,7 @@ enable_mmanplus(KBDC kbdc, struct psm_softc *sc)
if (MOUSE_PS2PLUS_PACKET_TYPE(data) != 0)
return (FALSE);
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.hwid &= 0x00ff;
sc->hw.hwid |= data[2] << 8; /* save model ID */
}
@@ -3946,8 +3946,9 @@ enable_mmanplus(KBDC kbdc, struct psm_softc *sc)
/* MS IntelliMouse Explorer */
static int
-enable_msexplorer(KBDC kbdc, struct psm_softc *sc)
+enable_msexplorer(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
static u_char rate0[] = { 200, 100, 80, };
static u_char rate1[] = { 200, 200, 80, };
int id;
@@ -3958,7 +3959,7 @@ enable_msexplorer(KBDC kbdc, struct psm_softc *sc)
* straight to Explorer mode, but need to be set to Intelli mode
* first.
*/
- enable_msintelli(kbdc, sc);
+ enable_msintelli(sc, arg);
/* the special sequence to enable the extra buttons and the roller. */
for (i = 0; i < sizeof(rate1)/sizeof(rate1[0]); ++i)
@@ -3969,7 +3970,7 @@ enable_msexplorer(KBDC kbdc, struct psm_softc *sc)
if (id != PSM_EXPLORER_ID)
return (FALSE);
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.buttons = 5; /* IntelliMouse Explorer XXX */
sc->hw.hwid = id;
}
@@ -3992,15 +3993,15 @@ enable_msexplorer(KBDC kbdc, struct psm_softc *sc)
return (TRUE);
}
-/* MS IntelliMouse */
+/*
+ * MS IntelliMouse
+ * Logitech MouseMan+ and FirstMouse+ will also respond to this
+ * probe routine and act like IntelliMouse.
+ */
static int
-enable_msintelli(KBDC kbdc, struct psm_softc *sc)
+enable_msintelli(struct psm_softc *sc, enum probearg arg)
{
- /*
- * Logitech MouseMan+ and FirstMouse+ will also respond to this
- * probe routine and act like IntelliMouse.
- */
-
+ KBDC kbdc = sc->kbdc;
static u_char rate[] = { 200, 100, 80, };
int id;
int i;
@@ -4014,7 +4015,7 @@ enable_msintelli(KBDC kbdc, struct psm_softc *sc)
if (id != PSM_INTELLI_ID)
return (FALSE);
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.buttons = 3;
sc->hw.hwid = id;
}
@@ -4022,15 +4023,15 @@ enable_msintelli(KBDC kbdc, struct psm_softc *sc)
return (TRUE);
}
-/* A4 Tech 4D Mouse */
+/*
+ * A4 Tech 4D Mouse
+ * Newer wheel mice from A4 Tech may use the 4D+ protocol.
+ */
static int
-enable_4dmouse(KBDC kbdc, struct psm_softc *sc)
+enable_4dmouse(struct psm_softc *sc, enum probearg arg)
{
- /*
- * Newer wheel mice from A4 Tech may use the 4D+ protocol.
- */
-
static u_char rate[] = { 200, 100, 80, 60, 40, 20 };
+ KBDC kbdc = sc->kbdc;
int id;
int i;
@@ -4046,7 +4047,7 @@ enable_4dmouse(KBDC kbdc, struct psm_softc *sc)
if (id != PSM_4DMOUSE_ID)
return (FALSE);
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.buttons = 3; /* XXX some 4D mice have 4? */
sc->hw.hwid = id;
}
@@ -4054,14 +4055,15 @@ enable_4dmouse(KBDC kbdc, struct psm_softc *sc)
return (TRUE);
}
-/* A4 Tech 4D+ Mouse */
+/*
+ * A4 Tech 4D+ Mouse
+ * Newer wheel mice from A4 Tech seem to use this protocol.
+ * Older models are recognized as either 4D Mouse or IntelliMouse.
+ */
static int
-enable_4dplus(KBDC kbdc, struct psm_softc *sc)
+enable_4dplus(struct psm_softc *sc, enum probearg arg)
{
- /*
- * Newer wheel mice from A4 Tech seem to use this protocol.
- * Older models are recognized as either 4D Mouse or IntelliMouse.
- */
+ KBDC kbdc = sc->kbdc;
int id;
/*
@@ -4084,7 +4086,7 @@ enable_4dplus(KBDC kbdc, struct psm_softc *sc)
return (FALSE);
}
- if (sc != NULL) {
+ if (arg == PROBE) {
sc->hw.buttons = (id == PSM_4DPLUS_ID) ? 4 : 3;
sc->hw.hwid = id;
}
@@ -4543,8 +4545,9 @@ synaptics_set_mode(struct psm_softc *sc, int mode_byte) {
}
static int
-enable_synaptics(KBDC kbdc, struct psm_softc *sc)
+enable_synaptics(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
synapticshw_t synhw;
int status[3];
int buttons;
@@ -4828,20 +4831,22 @@ enable_synaptics(KBDC kbdc, struct psm_softc *sc)
return (FALSE);
}
- if (sc != NULL)
+ if (arg == PROBE)
sc->synhw = synhw;
if (!synaptics_support)
return (FALSE);
+ synaptics_set_mode(sc, synaptics_preferred_mode(sc));
+
+ if (trackpoint_support && synhw.capPassthrough) {
+ synaptics_passthrough_on(sc);
+ enable_trackpoint(sc, arg);
+ synaptics_passthrough_off(sc);
+ }
+
VLOG(3, (LOG_DEBUG, "synaptics: END init (%d buttons)\n", buttons));
- if (sc != NULL) {
- synaptics_set_mode(sc, synaptics_preferred_mode(sc));
- if (trackpoint_support && synhw.capPassthrough) {
- synaptics_passthrough_on(sc);
- enable_trackpoint(kbdc, sc);
- synaptics_passthrough_off(sc);
- }
+ if (arg == PROBE) {
/* Create sysctl tree. */
synaptics_sysctl_create_tree(sc);
sc->hw.buttons = buttons;
@@ -5086,8 +5091,9 @@ set_trackpoint_parameters(struct psm_softc *sc)
}
static int
-enable_trackpoint(KBDC kbdc, struct psm_softc *sc)
+enable_trackpoint(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int id;
if (send_aux_command(kbdc, 0xe1) != PSM_ACK ||
@@ -5101,10 +5107,8 @@ enable_trackpoint(KBDC kbdc, struct psm_softc *sc)
if (!trackpoint_support)
return (FALSE);
- if (sc != NULL) {
- /* Create sysctl tree. */
+ if (arg == PROBE) {
trackpoint_sysctl_create_tree(sc);
-
/*
* Don't overwrite hwid and buttons when we are
* a guest device.
@@ -5115,13 +5119,16 @@ enable_trackpoint(KBDC kbdc, struct psm_softc *sc)
}
}
+ set_trackpoint_parameters(sc);
+
return (TRUE);
}
/* Interlink electronics VersaPad */
static int
-enable_versapad(KBDC kbdc, struct psm_softc *sc)
+enable_versapad(struct psm_softc *sc, enum probearg arg)
{
+ KBDC kbdc = sc->kbdc;
int data[3];
set_mouse_resolution(kbdc, PSMD_RES_MEDIUM_HIGH); /* set res. 2 */
diff --git a/sys/dev/bwi/bwimac.c b/sys/dev/bwi/bwimac.c
index 849bf022f1d4..f39ef44d4174 100644
--- a/sys/dev/bwi/bwimac.c
+++ b/sys/dev/bwi/bwimac.c
@@ -101,7 +101,6 @@ static void bwi_mac_opmode_init(struct bwi_mac *);
static void bwi_mac_hostflags_init(struct bwi_mac *);
static void bwi_mac_bss_param_init(struct bwi_mac *);
-static int bwi_mac_fw_alloc(struct bwi_mac *);
static void bwi_mac_fw_free(struct bwi_mac *);
static int bwi_mac_fw_load(struct bwi_mac *);
static int bwi_mac_fw_init(struct bwi_mac *);
@@ -325,10 +324,6 @@ bwi_mac_init(struct bwi_mac *mac)
/*
* Load and initialize firmwares
*/
- error = bwi_mac_fw_alloc(mac);
- if (error)
- return error;
-
error = bwi_mac_fw_load(mac);
if (error)
return error;
@@ -879,11 +874,10 @@ bwi_fwimage_is_valid(struct bwi_softc *sc, const struct firmware *fw,
/*
* XXX Error cleanup
*/
-static int
+int
bwi_mac_fw_alloc(struct bwi_mac *mac)
{
struct bwi_softc *sc = mac->mac_sc;
- struct ifnet *ifp = sc->sc_ifp;
char fwname[64];
int idx;
@@ -895,10 +889,8 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
snprintf(fwname, sizeof(fwname), BWI_FW_STUB_PATH,
sc->sc_fw_version);
mac->mac_stub = firmware_get(fwname);
- if (mac->mac_stub == NULL) {
- if_printf(ifp, "request firmware %s failed\n", fwname);
- return ENOMEM;
- }
+ if (mac->mac_stub == NULL)
+ goto no_firmware;
}
if (mac->mac_ucode == NULL) {
@@ -907,11 +899,8 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
mac->mac_rev >= 5 ? 5 : mac->mac_rev);
mac->mac_ucode = firmware_get(fwname);
- if (mac->mac_ucode == NULL) {
- if_printf(ifp, "request firmware %s failed\n", fwname);
- return ENOMEM;
- }
-
+ if (mac->mac_ucode == NULL)
+ goto no_firmware;
if (!bwi_fwimage_is_valid(sc, mac->mac_ucode, BWI_FW_T_UCODE))
return EINVAL;
}
@@ -922,11 +911,8 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
mac->mac_rev < 5 ? 4 : 5);
mac->mac_pcm = firmware_get(fwname);
- if (mac->mac_pcm == NULL) {
- if_printf(ifp, "request firmware %s failed\n", fwname);
- return ENOMEM;
- }
-
+ if (mac->mac_pcm == NULL)
+ goto no_firmware;
if (!bwi_fwimage_is_valid(sc, mac->mac_pcm, BWI_FW_T_PCM))
return EINVAL;
}
@@ -938,8 +924,8 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
} else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
idx = 5;
} else {
- if_printf(ifp, "no suitible IV for MAC rev %d\n",
- mac->mac_rev);
+ device_printf(sc->sc_dev,
+ "no suitible IV for MAC rev %d\n", mac->mac_rev);
return ENODEV;
}
@@ -947,10 +933,8 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
sc->sc_fw_version, idx);
mac->mac_iv = firmware_get(fwname);
- if (mac->mac_iv == NULL) {
- if_printf(ifp, "request firmware %s failed\n", fwname);
- return ENOMEM;
- }
+ if (mac->mac_iv == NULL)
+ goto no_firmware;
if (!bwi_fwimage_is_valid(sc, mac->mac_iv, BWI_FW_T_IV))
return EINVAL;
}
@@ -960,12 +944,12 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
if (mac->mac_rev == 2 || mac->mac_rev == 4 ||
mac->mac_rev >= 11) {
/* No extended IV */
- goto back;
+ return (0);
} else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
idx = 5;
} else {
- if_printf(ifp, "no suitible ExtIV for MAC rev %d\n",
- mac->mac_rev);
+ device_printf(sc->sc_dev,
+ "no suitible ExtIV for MAC rev %d\n", mac->mac_rev);
return ENODEV;
}
@@ -973,15 +957,16 @@ bwi_mac_fw_alloc(struct bwi_mac *mac)
sc->sc_fw_version, idx);
mac->mac_iv_ext = firmware_get(fwname);
- if (mac->mac_iv_ext == NULL) {
- if_printf(ifp, "request firmware %s failed\n", fwname);
- return ENOMEM;
- }
+ if (mac->mac_iv_ext == NULL)
+ goto no_firmware;
if (!bwi_fwimage_is_valid(sc, mac->mac_iv_ext, BWI_FW_T_IV))
return EINVAL;
}
-back:
- return 0;
+ return (0);
+
+no_firmware:
+ device_printf(sc->sc_dev, "request firmware %s failed\n", fwname);
+ return (ENOENT);
}
static void
diff --git a/sys/dev/bwi/bwimac.h b/sys/dev/bwi/bwimac.h
index 2c5275edfab7..a6d90083c60b 100644
--- a/sys/dev/bwi/bwimac.h
+++ b/sys/dev/bwi/bwimac.h
@@ -57,6 +57,7 @@ void bwi_mac_init_tpctl_11bg(struct bwi_mac *);
void bwi_mac_dummy_xmit(struct bwi_mac *);
void bwi_mac_reset_hwkeys(struct bwi_mac *);
int bwi_mac_config_ps(struct bwi_mac *);
+int bwi_mac_fw_alloc(struct bwi_mac *);
uint16_t bwi_memobj_read_2(struct bwi_mac *, uint16_t, uint16_t);
uint32_t bwi_memobj_read_4(struct bwi_mac *, uint16_t, uint16_t);
diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
index aa5369a1ca73..ad41bc675447 100644
--- a/sys/dev/bwi/if_bwi.c
+++ b/sys/dev/bwi/if_bwi.c
@@ -113,7 +113,7 @@ static void bwi_scan_start(struct ieee80211com *);
static void bwi_set_channel(struct ieee80211com *);
static void bwi_scan_end(struct ieee80211com *);
static int bwi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static void bwi_updateslot(struct ifnet *);
+static void bwi_updateslot(struct ieee80211com *);
static int bwi_media_change(struct ifnet *);
static void bwi_calibrate(void *);
@@ -446,6 +446,10 @@ bwi_attach(struct bwi_softc *sc)
if (error)
goto fail;
+ error = bwi_mac_fw_alloc(mac);
+ if (error)
+ goto fail;
+
ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
if (ifp == NULL) {
device_printf(dev, "can not if_alloc()\n");
@@ -507,6 +511,8 @@ bwi_attach(struct bwi_softc *sc)
ieee80211_init_channels(ic, NULL, &bands);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_caps = IEEE80211_C_STA |
IEEE80211_C_SHSLOT |
IEEE80211_C_SHPREAMBLE |
@@ -1919,7 +1925,7 @@ bwi_dma_alloc(struct bwi_softc *sc)
BUS_SPACE_MAXSIZE, /* maxsize */
BUS_SPACE_UNRESTRICTED, /* nsegments */
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- BUS_DMA_ALLOCNOW, /* flags */
+ 0, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->sc_parent_dtag);
if (error) {
@@ -1939,8 +1945,8 @@ bwi_dma_alloc(struct bwi_softc *sc)
NULL, NULL,
tx_ring_sz,
1,
- BUS_SPACE_MAXSIZE_32BIT,
- BUS_DMA_ALLOCNOW,
+ tx_ring_sz,
+ 0,
NULL, NULL,
&sc->sc_txring_dtag);
if (error) {
@@ -1969,8 +1975,8 @@ bwi_dma_alloc(struct bwi_softc *sc)
NULL, NULL,
rx_ring_sz,
1,
- BUS_SPACE_MAXSIZE_32BIT,
- BUS_DMA_ALLOCNOW,
+ rx_ring_sz,
+ 0,
NULL, NULL,
&sc->sc_rxring_dtag);
if (error) {
@@ -2094,8 +2100,8 @@ bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
NULL, NULL,
dma_size,
1,
- BUS_SPACE_MAXSIZE_32BIT,
- BUS_DMA_ALLOCNOW,
+ dma_size,
+ 0,
NULL, NULL,
&st->stats_ring_dtag);
if (error) {
@@ -2142,8 +2148,8 @@ bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
NULL, NULL,
dma_size,
1,
- BUS_SPACE_MAXSIZE_32BIT,
- BUS_DMA_ALLOCNOW,
+ dma_size,
+ 0,
NULL, NULL,
&st->stats_dtag);
if (error) {
@@ -2225,7 +2231,7 @@ bwi_dma_mbuf_create(struct bwi_softc *sc)
NULL, NULL,
MCLBYTES,
1,
- BUS_SPACE_MAXSIZE_32BIT,
+ MCLBYTES,
BUS_DMA_ALLOCNOW,
NULL, NULL,
&sc->sc_buf_dtag);
@@ -3733,14 +3739,13 @@ bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
}
static void
-bwi_updateslot(struct ifnet *ifp)
+bwi_updateslot(struct ieee80211com *ic)
{
- struct bwi_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct bwi_softc *sc = ic->ic_softc;
struct bwi_mac *mac;
BWI_LOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) {
DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__);
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
diff --git a/sys/dev/bwi/if_bwi_pci.c b/sys/dev/bwi/if_bwi_pci.c
index 1977b93a4acc..c2badc504a9b 100644
--- a/sys/dev/bwi/if_bwi_pci.c
+++ b/sys/dev/bwi/if_bwi_pci.c
@@ -161,12 +161,6 @@ bwi_pci_attach(device_t dev)
device_printf(dev, "could not map interrupt\n");
goto bad1;
}
- if (bus_setup_intr(dev, sc->sc_irq_res,
- INTR_TYPE_NET | INTR_MPSAFE,
- NULL, bwi_intr, sc, &sc->sc_irq_handle)) {
- device_printf(dev, "could not establish interrupt\n");
- goto bad2;
- }
/* Get more PCI information */
sc->sc_pci_did = pci_get_device(dev);
@@ -174,11 +168,17 @@ bwi_pci_attach(device_t dev)
sc->sc_pci_subvid = pci_get_subvendor(dev);
sc->sc_pci_subdid = pci_get_subdevice(dev);
- error = bwi_attach(sc);
- if (error == 0) /* success */
- return 0;
+ if ((error = bwi_attach(sc)) != 0)
+ goto bad2;
+
+ if (bus_setup_intr(dev, sc->sc_irq_res,
+ INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, bwi_intr, sc, &sc->sc_irq_handle)) {
+ device_printf(dev, "could not establish interrupt\n");
+ goto bad2;
+ }
+ return (0);
- bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_handle);
bad2:
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
bad1:
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index 959d1f131423..823908ad3278 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -181,8 +181,8 @@ static void bwn_addchannels(struct ieee80211_channel [], int, int *,
const struct bwn_channelinfo *, int);
static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void bwn_updateslot(struct ifnet *);
-static void bwn_update_promisc(struct ifnet *);
+static void bwn_updateslot(struct ieee80211com *);
+static void bwn_update_promisc(struct ieee80211com *);
static void bwn_wme_init(struct bwn_mac *);
static int bwn_wme_update(struct ieee80211com *);
static void bwn_wme_clear(struct bwn_softc *);
@@ -1058,6 +1058,8 @@ bwn_attach_post(struct bwn_softc *sc)
ic = ifp->if_l2com;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(sc->sc_dev);
/* XXX not right but it's not used anywhere important */
ic->ic_phytype = IEEE80211_T_OFDM;
ic->ic_opmode = IEEE80211_M_STA;
@@ -1250,7 +1252,7 @@ bwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCSIFFLAGS:
startall = 0;
if (IS_RUNNING(ifp)) {
- bwn_update_promisc(ifp);
+ bwn_update_promisc(ic);
} else if (ifp->if_flags & IFF_UP) {
if ((sc->sc_flags & BWN_FLAG_INVALID) == 0) {
bwn_init(sc);
@@ -2770,14 +2772,13 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
* like slot time and preamble.
*/
static void
-bwn_updateslot(struct ifnet *ifp)
+bwn_updateslot(struct ieee80211com *ic)
{
- struct bwn_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac;
BWN_LOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) {
mac = (struct bwn_mac *)sc->sc_curmac;
bwn_set_slot_time(mac,
(ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20);
@@ -2793,15 +2794,15 @@ bwn_updateslot(struct ifnet *ifp)
* mode when operating in hostap mode to do ACS).
*/
static void
-bwn_update_promisc(struct ifnet *ifp)
+bwn_update_promisc(struct ieee80211com *ic)
{
- struct bwn_softc *sc = ifp->if_softc;
+ struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac = sc->sc_curmac;
BWN_LOCK(sc);
mac = sc->sc_curmac;
if (mac != NULL && mac->mac_status >= BWN_MAC_STATUS_INITED) {
- if (ifp->if_flags & IFF_PROMISC)
+ if (ic->ic_ifp->if_flags & IFF_PROMISC)
sc->sc_filters |= BWN_MACCTL_PROMISC;
else
sc->sc_filters &= ~BWN_MACCTL_PROMISC;
diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c
index 00e367aaab54..f274016c8630 100644
--- a/sys/dev/bxe/bxe.c
+++ b/sys/dev/bxe/bxe.c
@@ -726,7 +726,6 @@ static __noinline int bxe_nic_unload(struct bxe_softc *sc,
uint8_t keep_link);
static void bxe_handle_sp_tq(void *context, int pending);
-static void bxe_handle_rx_mode_tq(void *context, int pending);
static void bxe_handle_fp_tq(void *context, int pending);
@@ -1174,7 +1173,17 @@ bxe_release_hw_lock(struct bxe_softc *sc,
REG_WR(sc, hw_lock_control_reg, resource_bit);
return (0);
}
+static void bxe_acquire_phy_lock(struct bxe_softc *sc)
+{
+ BXE_PHY_LOCK(sc);
+ bxe_acquire_hw_lock(sc,HW_LOCK_RESOURCE_MDIO);
+}
+static void bxe_release_phy_lock(struct bxe_softc *sc)
+{
+ bxe_release_hw_lock(sc,HW_LOCK_RESOURCE_MDIO);
+ BXE_PHY_UNLOCK(sc);
+}
/*
* Per pf misc lock must be acquired before the per port mcp lock. Otherwise,
* had we done things the other way around, if two pfs from the same port
@@ -4764,28 +4773,6 @@ bxe_handle_chip_tq(void *context,
switch (work)
{
- case CHIP_TQ_START:
- if ((if_getflags(sc->ifp) & IFF_UP) &&
- !(if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
- /* start the interface */
- BLOGD(sc, DBG_LOAD, "Starting the interface...\n");
- BXE_CORE_LOCK(sc);
- bxe_init_locked(sc);
- BXE_CORE_UNLOCK(sc);
- }
- break;
-
- case CHIP_TQ_STOP:
- if (!(if_getflags(sc->ifp) & IFF_UP) &&
- (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
- /* bring down the interface */
- BLOGD(sc, DBG_LOAD, "Stopping the interface...\n");
- bxe_periodic_stop(sc);
- BXE_CORE_LOCK(sc);
- bxe_stop_locked(sc);
- BXE_CORE_UNLOCK(sc);
- }
- break;
case CHIP_TQ_REINIT:
if (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) {
@@ -4859,21 +4846,22 @@ bxe_ioctl(if_t ifp,
/* toggle the interface state up or down */
BLOGD(sc, DBG_IOCTL, "Received SIOCSIFFLAGS ioctl\n");
+ BXE_CORE_LOCK(sc);
/* check if the interface is up */
if (if_getflags(ifp) & IFF_UP) {
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
/* set the receive mode flags */
bxe_set_rx_mode(sc);
} else {
- atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_START);
- taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
+ bxe_init_locked(sc);
}
} else {
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
- atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_STOP);
- taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
+ bxe_periodic_stop(sc);
+ bxe_stop_locked(sc);
}
}
+ BXE_CORE_UNLOCK(sc);
break;
@@ -4885,7 +4873,9 @@ bxe_ioctl(if_t ifp,
/* check if the interface is up */
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
/* set the receive mode flags */
+ BXE_CORE_LOCK(sc);
bxe_set_rx_mode(sc);
+ BXE_CORE_UNLOCK(sc);
}
break;
@@ -5044,8 +5034,11 @@ bxe_ioctl(if_t ifp,
if (reinit && (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
BLOGD(sc, DBG_LOAD | DBG_IOCTL,
"Re-initializing hardware from IOCTL change\n");
- atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_REINIT);
- taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
+ bxe_periodic_stop(sc);
+ BXE_CORE_LOCK(sc);
+ bxe_stop_locked(sc);
+ bxe_init_locked(sc);
+ BXE_CORE_UNLOCK(sc);
}
return (error);
@@ -7487,8 +7480,7 @@ bxe_attn_int_asserted(struct bxe_softc *sc,
if (asserted & ATTN_HARD_WIRED_MASK) {
if (asserted & ATTN_NIG_FOR_FUNC) {
- BXE_PHY_LOCK(sc);
-
+ bxe_acquire_phy_lock(sc);
/* save nig interrupt mask */
nig_mask = REG_RD(sc, nig_int_mask_addr);
@@ -7581,7 +7573,7 @@ bxe_attn_int_asserted(struct bxe_softc *sc,
REG_WR(sc, nig_int_mask_addr, nig_mask);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
}
@@ -8339,10 +8331,10 @@ bxe_attn_int_deasserted3(struct bxe_softc *sc,
if (sc->link_vars.periodic_flags &
ELINK_PERIODIC_FLAGS_LINK_EVENT) {
/* sync with link */
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
sc->link_vars.periodic_flags &=
~ELINK_PERIODIC_FLAGS_LINK_EVENT;
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
if (IS_MF(sc))
; // XXX bxe_link_sync_notify(sc);
bxe_link_report(sc);
@@ -8535,9 +8527,9 @@ bxe_attn_int_deasserted0(struct bxe_softc *sc,
}
if ((attn & sc->link_vars.aeu_int_mask) && sc->port.pmf) {
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
elink_handle_module_detect_int(&sc->link_params);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
if (attn & HW_INTERRUT_ASSERT_SET_0) {
@@ -9564,11 +9556,6 @@ bxe_interrupt_detach(struct bxe_softc *sc)
}
}
- if (sc->rx_mode_tq) {
- taskqueue_drain(sc->rx_mode_tq, &sc->rx_mode_tq_task);
- taskqueue_free(sc->rx_mode_tq);
- sc->rx_mode_tq = NULL;
- }
if (sc->sp_tq) {
taskqueue_drain(sc->sp_tq, &sc->sp_tq_task);
@@ -9602,14 +9589,6 @@ bxe_interrupt_attach(struct bxe_softc *sc)
taskqueue_start_threads(&sc->sp_tq, 1, PWAIT, /* lower priority */
"%s", sc->sp_tq_name);
- snprintf(sc->rx_mode_tq_name, sizeof(sc->rx_mode_tq_name),
- "bxe%d_rx_mode_tq", sc->unit);
- TASK_INIT(&sc->rx_mode_tq_task, 0, bxe_handle_rx_mode_tq, sc);
- sc->rx_mode_tq = taskqueue_create_fast(sc->rx_mode_tq_name, M_NOWAIT,
- taskqueue_thread_enqueue,
- &sc->rx_mode_tq);
- taskqueue_start_threads(&sc->rx_mode_tq, 1, PWAIT, /* lower priority */
- "%s", sc->rx_mode_tq_name);
for (i = 0; i < sc->num_queues; i++) {
fp = &sc->fp[i];
@@ -12363,9 +12342,9 @@ bxe_link_report_locked(struct bxe_softc *sc)
static void
bxe_link_report(struct bxe_softc *sc)
{
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
bxe_link_report_locked(sc);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
static void
@@ -12481,7 +12460,7 @@ bxe_initial_phy_init(struct bxe_softc *sc,
sc->link_params.feature_config_flags |= feat;
}
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
if (load_mode == LOAD_DIAG) {
lp->loopback_mode = ELINK_LOOPBACK_XGXS;
@@ -12502,7 +12481,7 @@ bxe_initial_phy_init(struct bxe_softc *sc,
rc = elink_phy_init(&sc->link_params, &sc->link_vars);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
bxe_calc_fc_adv(sc);
@@ -12694,18 +12673,13 @@ bxe_set_uc_list(struct bxe_softc *sc)
}
static void
-bxe_handle_rx_mode_tq(void *context,
- int pending)
+bxe_set_rx_mode(struct bxe_softc *sc)
{
- struct bxe_softc *sc = (struct bxe_softc *)context;
if_t ifp = sc->ifp;
uint32_t rx_mode = BXE_RX_MODE_NORMAL;
- BXE_CORE_LOCK(sc);
-
if (sc->state != BXE_STATE_OPEN) {
BLOGD(sc, DBG_SP, "state is %x, returning\n", sc->state);
- BXE_CORE_UNLOCK(sc);
return;
}
@@ -12747,7 +12721,6 @@ bxe_handle_rx_mode_tq(void *context,
if (bxe_test_bit(ECORE_FILTER_RX_MODE_PENDING, &sc->sp_state)) {
BLOGD(sc, DBG_LOAD, "Scheduled setting rx_mode with ECORE...\n");
bxe_set_bit(ECORE_FILTER_RX_MODE_SCHED, &sc->sp_state);
- BXE_CORE_UNLOCK(sc);
return;
}
@@ -12767,14 +12740,8 @@ bxe_handle_rx_mode_tq(void *context,
}
#endif
- BXE_CORE_UNLOCK(sc);
}
-static void
-bxe_set_rx_mode(struct bxe_softc *sc)
-{
- taskqueue_enqueue(sc->rx_mode_tq, &sc->rx_mode_tq_task);
-}
/* update flags in shmem */
static void
@@ -12845,13 +12812,13 @@ bxe_periodic_callout_func(void *xsc)
*/
mb();
if (sc->port.pmf) {
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
elink_period_func(&sc->link_params, &sc->link_vars);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
}
- if (IS_PF(sc) && !BXE_NOMCP(sc)) {
+ if (IS_PF(sc) && !(sc->flags & BXE_NO_PULSE)) {
int mb_idx = SC_FW_MB_IDX(sc);
uint32_t drv_pulse;
uint32_t mcp_pulse;
@@ -12995,6 +12962,11 @@ bxe_nic_load(struct bxe_softc *sc,
}
}
+ /* set ALWAYS_ALIVE bit in shmem */
+ sc->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE;
+ bxe_drv_pulse(sc);
+ sc->flags |= BXE_NO_PULSE;
+
/* attach interrupts */
if (bxe_interrupt_attach(sc) != 0) {
sc->state = BXE_STATE_CLOSED;
@@ -16750,10 +16722,10 @@ bxe_common_init_phy(struct bxe_softc *sc)
shmem2_base[1] = SHMEM2_RD(sc, other_shmem2_base_addr);
}
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
elink_common_init_phy(sc, shmem_base, shmem2_base,
sc->devinfo.chip_id, 0);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
}
static void
@@ -18630,9 +18602,9 @@ static void
bxe_link_reset(struct bxe_softc *sc)
{
if (!BXE_NOMCP(sc)) {
- BXE_PHY_LOCK(sc);
+ bxe_acquire_phy_lock(sc);
elink_lfa_reset(&sc->link_params, &sc->link_vars);
- BXE_PHY_UNLOCK(sc);
+ bxe_release_phy_lock(sc);
} else {
if (!CHIP_REV_IS_SLOW(sc)) {
BLOGW(sc, "Bootcode is missing - cannot reset link\n");
diff --git a/sys/dev/bxe/bxe.h b/sys/dev/bxe/bxe.h
index eb695d045211..5fb31a32ba87 100644
--- a/sys/dev/bxe/bxe.h
+++ b/sys/dev/bxe/bxe.h
@@ -1400,6 +1400,7 @@ struct bxe_softc {
//#define BXE_SAFC_TX_FLAG 0x00000400
#define BXE_MF_FUNC_DIS 0x00000800
#define BXE_TX_SWITCHING 0x00001000
+#define BXE_NO_PULSE 0x00002000
unsigned long debug; /* per-instance debug logging config */
@@ -1429,11 +1430,6 @@ struct bxe_softc {
struct taskqueue *sp_tq;
char sp_tq_name[32];
- /* set rx_mode asynchronous taskqueue */
- struct task rx_mode_tq_task;
- struct taskqueue *rx_mode_tq;
- char rx_mode_tq_name[32];
-
struct bxe_fastpath fp[MAX_RSS_CHAINS];
struct bxe_sp_objs sp_objs[MAX_RSS_CHAINS];
diff --git a/sys/dev/bxe/ecore_reg.h b/sys/dev/bxe/ecore_reg.h
index b256e7843ecc..850390c2fe4a 100644
--- a/sys/dev/bxe/ecore_reg.h
+++ b/sys/dev/bxe/ecore_reg.h
@@ -1965,6 +1965,7 @@ __FBSDID("$FreeBSD$");
#define MISC_SPIO_SPIO5 0x20
#define HW_LOCK_MAX_RESOURCE_VALUE 31
#define HW_LOCK_RESOURCE_DRV_FLAGS 10
+#define HW_LOCK_RESOURCE_MDIO 0
#define HW_LOCK_RESOURCE_GPIO 1
#define HW_LOCK_RESOURCE_NVRAM 12
#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index f5b26441701a..b164cce731e2 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -582,7 +582,6 @@ t4_attach(device_t dev)
#ifdef DEV_NETMAP
int nm_rqidx, nm_tqidx;
#endif
- const char *pcie_ts;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -905,25 +904,10 @@ t4_attach(device_t dev)
goto done;
}
- switch (sc->params.pci.speed) {
- case 0x1:
- pcie_ts = "2.5";
- break;
- case 0x2:
- pcie_ts = "5.0";
- break;
- case 0x3:
- pcie_ts = "8.0";
- break;
- default:
- pcie_ts = "??";
- break;
- }
device_printf(dev,
- "PCIe x%d (%s GTS/s) (%d), %d ports, %d %s interrupt%s, %d eq, %d iq\n",
- sc->params.pci.width, pcie_ts, sc->params.pci.speed,
- sc->params.nports, sc->intr_count,
- sc->intr_type == INTR_MSIX ? "MSI-X" :
+ "PCIe gen%d x%d, %d ports, %d %s interrupt%s, %d eq, %d iq\n",
+ sc->params.pci.speed, sc->params.pci.width, sc->params.nports,
+ sc->intr_count, sc->intr_type == INTR_MSIX ? "MSI-X" :
(sc->intr_type == INTR_MSI ? "MSI" : "INTx"),
sc->intr_count > 1 ? "s" : "", sc->sge.neq, sc->sge.niq);
diff --git a/sys/dev/cxgbe/t4_netmap.c b/sys/dev/cxgbe/t4_netmap.c
index 7d4860381222..c73914605df7 100644
--- a/sys/dev/cxgbe/t4_netmap.c
+++ b/sys/dev/cxgbe/t4_netmap.c
@@ -297,7 +297,7 @@ alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq, int cong)
(fl_pad ? F_FW_IQ_CMD_FL0PADEN : 0) |
(black_hole == 2 ? F_FW_IQ_CMD_FL0PACKEN : 0));
c.fl0dcaen_to_fl0cidxfthresh =
- htobe16(V_FW_IQ_CMD_FL0FBMIN(X_FETCHBURSTMIN_64B) |
+ htobe16(V_FW_IQ_CMD_FL0FBMIN(X_FETCHBURSTMIN_128B) |
V_FW_IQ_CMD_FL0FBMAX(X_FETCHBURSTMAX_512B));
c.fl0size = htobe16(na->num_rx_desc / 8 + spg_len / EQ_ESIZE);
c.fl0addr = htobe64(nm_rxq->fl_ba);
diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c
index 94162527d0fe..27e1ccf496f5 100644
--- a/sys/dev/cxgbe/t4_sge.c
+++ b/sys/dev/cxgbe/t4_sge.c
@@ -2665,7 +2665,7 @@ alloc_iq_fl(struct port_info *pi, struct sge_iq *iq, struct sge_fl *fl,
F_FW_IQ_CMD_FL0CONGEN);
}
c.fl0dcaen_to_fl0cidxfthresh =
- htobe16(V_FW_IQ_CMD_FL0FBMIN(X_FETCHBURSTMIN_64B) |
+ htobe16(V_FW_IQ_CMD_FL0FBMIN(X_FETCHBURSTMIN_128B) |
V_FW_IQ_CMD_FL0FBMAX(X_FETCHBURSTMAX_512B));
c.fl0size = htobe16(fl->qsize);
c.fl0addr = htobe64(fl->ba);
diff --git a/sys/dev/drm/drmP.h b/sys/dev/drm/drmP.h
index bf5feedc7e6e..7725884693a8 100644
--- a/sys/dev/drm/drmP.h
+++ b/sys/dev/drm/drmP.h
@@ -51,9 +51,7 @@ struct drm_file;
#include <sys/conf.h>
#include <sys/sglist.h>
#include <sys/stat.h>
-#if __FreeBSD_version >= 700000
#include <sys/priv.h>
-#endif
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/fcntl.h>
@@ -94,11 +92,7 @@ struct drm_file;
#include <sys/mman.h>
#include <sys/rman.h>
#include <sys/memrange.h>
-#if __FreeBSD_version >= 800004
#include <dev/agp/agpvar.h>
-#else /* __FreeBSD_version >= 800004 */
-#include <pci/agpvar.h>
-#endif /* __FreeBSD_version >= 800004 */
#include <sys/agpio.h>
#include <sys/mutex.h>
#include <dev/pci/pcivar.h>
@@ -227,11 +221,7 @@ enum {
#define PAGE_ALIGN(addr) round_page(addr)
/* DRM_SUSER returns true if the user is superuser */
-#if __FreeBSD_version >= 700000
#define DRM_SUSER(p) (priv_check(p, PRIV_DRIVER) == 0)
-#else
-#define DRM_SUSER(p) (suser(p) == 0)
-#endif
#define DRM_AGP_FIND_DEVICE() agp_find_device()
#define DRM_MTRR_WC MDF_WRITECOMBINE
#define jiffies ticks
diff --git a/sys/dev/drm/drm_agpsupport.c b/sys/dev/drm/drm_agpsupport.c
index 6a7ebcf5e9ef..4bb4e7a6ca1d 100644
--- a/sys/dev/drm/drm_agpsupport.c
+++ b/sys/dev/drm/drm_agpsupport.c
@@ -38,50 +38,15 @@ __FBSDID("$FreeBSD$");
#include "dev/drm/drmP.h"
-#if __FreeBSD_version >= 800004
#include <dev/agp/agpreg.h>
-#else /* __FreeBSD_version >= 800004 */
-#include <pci/agpreg.h>
-#endif /* __FreeBSD_version >= 800004 */
#include <dev/pci/pcireg.h>
/* Returns 1 if AGP or 0 if not. */
static int
drm_device_find_capability(struct drm_device *dev, int cap)
{
-#if __FreeBSD_version >= 602102
return (pci_find_cap(dev->device, cap, NULL) == 0);
-#else
- /* Code taken from agp.c. IWBNI that was a public interface. */
- u_int32_t status;
- u_int8_t ptr, next;
-
- /*
- * Check the CAP_LIST bit of the PCI status register first.
- */
- status = pci_read_config(dev->device, PCIR_STATUS, 2);
- if (!(status & 0x10))
- return 0;
-
- /*
- * Traverse the capabilities list.
- */
- for (ptr = pci_read_config(dev->device, AGP_CAPPTR, 1);
- ptr != 0;
- ptr = next) {
- u_int32_t capid = pci_read_config(dev->device, ptr, 4);
- next = AGP_CAPID_GET_NEXT_PTR(capid);
-
- /*
- * If this capability entry ID is cap, then we are done.
- */
- if (AGP_CAPID_GET_CAP_ID(capid) == cap)
- return 1;
- }
-
- return 0;
-#endif
}
int drm_device_is_agp(struct drm_device *dev)
diff --git a/sys/dev/drm/drm_bufs.c b/sys/dev/drm/drm_bufs.c
index 2d27cd4b88b5..b685a591c01f 100644
--- a/sys/dev/drm/drm_bufs.c
+++ b/sys/dev/drm/drm_bufs.c
@@ -1066,15 +1066,9 @@ int drm_mapbufs(struct drm_device *dev, void *data, struct drm_file *file_priv)
}
vaddr = round_page((vm_offset_t)vms->vm_daddr + MAXDSIZ);
-#if __FreeBSD_version >= 600023
- retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
- VM_PROT_ALL, MAP_SHARED | MAP_NOSYNC, OBJT_DEVICE,
+ retcode = vm_mmap(&vms->vm_map, &vaddr, size, VM_PROT_READ |
+ VM_PROT_WRITE, VM_PROT_ALL, MAP_SHARED | MAP_NOSYNC, OBJT_DEVICE,
dev->devnode, foff);
-#else
- retcode = vm_mmap(&vms->vm_map, &vaddr, size, PROT_READ | PROT_WRITE,
- VM_PROT_ALL, MAP_SHARED | MAP_NOSYNC,
- SLIST_FIRST(&dev->devnode->si_hlist), foff);
-#endif
if (retcode)
goto done;
diff --git a/sys/dev/drm/drm_drv.c b/sys/dev/drm/drm_drv.c
index 75983766f379..6874d45d0335 100644
--- a/sys/dev/drm/drm_drv.c
+++ b/sys/dev/drm/drm_drv.c
@@ -161,19 +161,8 @@ int drm_probe(device_t kdev, drm_pci_id_list_t *idlist)
{
drm_pci_id_list_t *id_entry;
int vendor, device;
-#if __FreeBSD_version < 700010
- device_t realdev;
-
- if (!strcmp(device_get_name(kdev), "drmsub"))
- realdev = device_get_parent(kdev);
- else
- realdev = kdev;
- vendor = pci_get_vendor(realdev);
- device = pci_get_device(realdev);
-#else
vendor = pci_get_vendor(kdev);
device = pci_get_device(kdev);
-#endif
if (pci_get_class(kdev) != PCIC_DISPLAY
|| pci_get_subclass(kdev) != PCIS_DISPLAY_VGA)
@@ -200,14 +189,7 @@ int drm_attach(device_t kdev, drm_pci_id_list_t *idlist)
unit = device_get_unit(kdev);
dev = device_get_softc(kdev);
-#if __FreeBSD_version < 700010
- if (!strcmp(device_get_name(kdev), "drmsub"))
- dev->device = device_get_parent(kdev);
- else
- dev->device = kdev;
-#else
dev->device = kdev;
-#endif
dev->devnode = make_dev(&drm_cdevsw,
0,
DRM_DEV_UID,
@@ -216,11 +198,7 @@ int drm_attach(device_t kdev, drm_pci_id_list_t *idlist)
"dri/card%d", unit);
dev->devnode->si_drv1 = dev;
-#if __FreeBSD_version >= 700053
dev->pci_domain = pci_get_domain(dev->device);
-#else
- dev->pci_domain = 0;
-#endif
dev->pci_bus = pci_get_bus(dev->device);
dev->pci_slot = pci_get_slot(dev->device);
dev->pci_func = pci_get_function(dev->device);
diff --git a/sys/dev/drm/drm_irq.c b/sys/dev/drm/drm_irq.c
index 8977bcf8a562..596569952bbb 100644
--- a/sys/dev/drm/drm_irq.c
+++ b/sys/dev/drm/drm_irq.c
@@ -175,15 +175,9 @@ int drm_irq_install(struct drm_device *dev)
DRM_UNLOCK();
/* Install handler */
-#if __FreeBSD_version >= 700031
retcode = bus_setup_intr(dev->device, dev->irqr,
INTR_TYPE_TTY | INTR_MPSAFE,
NULL, drm_irq_handler_wrap, dev, &dev->irqh);
-#else
- retcode = bus_setup_intr(dev->device, dev->irqr,
- INTR_TYPE_TTY | INTR_MPSAFE,
- drm_irq_handler_wrap, dev, &dev->irqh);
-#endif
if (retcode != 0)
goto err;
diff --git a/sys/dev/drm/i915_drv.c b/sys/dev/drm/i915_drv.c
index 8638df14bd32..244c7feec85a 100644
--- a/sys/dev/drm/i915_drv.c
+++ b/sys/dev/drm/i915_drv.c
@@ -147,19 +147,11 @@ static device_method_t i915_methods[] = {
};
static driver_t i915_driver = {
-#if __FreeBSD_version >= 700010
"drm",
-#else
- "drmsub",
-#endif
i915_methods,
sizeof(struct drm_device)
};
extern devclass_t drm_devclass;
-#if __FreeBSD_version >= 700010
DRIVER_MODULE(i915, vgapci, i915_driver, drm_devclass, 0, 0);
-#else
-DRIVER_MODULE(i915, agp, i915_driver, drm_devclass, 0, 0);
-#endif
MODULE_DEPEND(i915, drm, 1, 1, 1);
diff --git a/sys/dev/drm/mach64_drv.c b/sys/dev/drm/mach64_drv.c
index 6f859ec953fe..f4f61cdd3e3a 100644
--- a/sys/dev/drm/mach64_drv.c
+++ b/sys/dev/drm/mach64_drv.c
@@ -130,9 +130,5 @@ static driver_t mach64_driver = {
};
extern devclass_t drm_devclass;
-#if __FreeBSD_version >= 700010
DRIVER_MODULE(mach64, vgapci, mach64_driver, drm_devclass, 0, 0);
-#else
-DRIVER_MODULE(mach64, pci, mach64_driver, drm_devclass, 0, 0);
-#endif
MODULE_DEPEND(mach64, drm, 1, 1, 1);
diff --git a/sys/dev/drm/mga_drv.c b/sys/dev/drm/mga_drv.c
index 6bb7e2b11ee9..bc585b476096 100644
--- a/sys/dev/drm/mga_drv.c
+++ b/sys/dev/drm/mga_drv.c
@@ -74,11 +74,7 @@ static int mga_driver_device_is_agp(struct drm_device * dev)
* device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
* device.
*/
-#if __FreeBSD_version >= 700010
bus = device_get_parent(device_get_parent(dev->device));
-#else
- bus = device_get_parent(dev->device);
-#endif
if (pci_get_device(dev->device) == 0x0525 &&
pci_get_vendor(bus) == 0x3388 &&
pci_get_device(bus) == 0x0021)
@@ -167,9 +163,5 @@ static driver_t mga_driver = {
};
extern devclass_t drm_devclass;
-#if __FreeBSD_version >= 700010
DRIVER_MODULE(mga, vgapci, mga_driver, drm_devclass, 0, 0);
-#else
-DRIVER_MODULE(mga, pci, mga_driver, drm_devclass, 0, 0);
-#endif
MODULE_DEPEND(mga, drm, 1, 1, 1);
diff --git a/sys/dev/drm/r128_drv.c b/sys/dev/drm/r128_drv.c
index 8aebb0c07982..a112aebe2410 100644
--- a/sys/dev/drm/r128_drv.c
+++ b/sys/dev/drm/r128_drv.c
@@ -128,9 +128,5 @@ static driver_t r128_driver = {
};
extern devclass_t drm_devclass;
-#if __FreeBSD_version >= 700010
DRIVER_MODULE(r128, vgapci, r128_driver, drm_devclass, 0, 0);
-#else
-DRIVER_MODULE(r128, pci, r128_driver, drm_devclass, 0, 0);
-#endif
MODULE_DEPEND(r128, drm, 1, 1, 1);
diff --git a/sys/dev/drm/radeon_drv.c b/sys/dev/drm/radeon_drv.c
index 53443bc99d93..a37c641dc878 100644
--- a/sys/dev/drm/radeon_drv.c
+++ b/sys/dev/drm/radeon_drv.c
@@ -127,9 +127,5 @@ static driver_t radeon_driver = {
};
extern devclass_t drm_devclass;
-#if __FreeBSD_version >= 700010
DRIVER_MODULE(radeon, vgapci, radeon_driver, drm_devclass, 0, 0);
-#else
-DRIVER_MODULE(radeon, pci, radeon_driver, drm_devclass, 0, 0);
-#endif
MODULE_DEPEND(radeon, drm, 1, 1, 1);
diff --git a/sys/dev/drm/savage_drv.c b/sys/dev/drm/savage_drv.c
index 3c5e7c89c805..f6accaed7fac 100644
--- a/sys/dev/drm/savage_drv.c
+++ b/sys/dev/drm/savage_drv.c
@@ -113,9 +113,5 @@ static driver_t savage_driver = {
};
extern devclass_t drm_devclass;
-#if __FreeBSD_version >= 700010
DRIVER_MODULE(savage, vgapci, savage_driver, drm_devclass, 0, 0);
-#else
-DRIVER_MODULE(savage, pci, savage_driver, drm_devclass, 0, 0);
-#endif
MODULE_DEPEND(savage, drm, 1, 1, 1);
diff --git a/sys/dev/drm/sis_drv.c b/sys/dev/drm/sis_drv.c
index 8da88ba30304..8e82ac09fae2 100644
--- a/sys/dev/drm/sis_drv.c
+++ b/sys/dev/drm/sis_drv.c
@@ -107,9 +107,5 @@ static driver_t sis_driver = {
};
extern devclass_t drm_devclass;
-#if __FreeBSD_version >= 700010
DRIVER_MODULE(sisdrm, vgapci, sis_driver, drm_devclass, 0, 0);
-#else
-DRIVER_MODULE(sisdrm, pci, sis_driver, drm_devclass, 0, 0);
-#endif
MODULE_DEPEND(sisdrm, drm, 1, 1, 1);
diff --git a/sys/dev/drm/tdfx_drv.c b/sys/dev/drm/tdfx_drv.c
index 75b7acaa751f..2fe9eee634c8 100644
--- a/sys/dev/drm/tdfx_drv.c
+++ b/sys/dev/drm/tdfx_drv.c
@@ -109,9 +109,5 @@ static driver_t tdfx_driver = {
};
extern devclass_t drm_devclass;
-#if __FreeBSD_version >= 700010
DRIVER_MODULE(tdfx, vgapci, tdfx_driver, drm_devclass, 0, 0);
-#else
-DRIVER_MODULE(tdfx, pci, tdfx_driver, drm_devclass, 0, 0);
-#endif
MODULE_DEPEND(tdfx, drm, 1, 1, 1);
diff --git a/sys/dev/drm2/drm_bufs.c b/sys/dev/drm2/drm_bufs.c
index 135946685cba..483ee55e06d1 100644
--- a/sys/dev/drm2/drm_bufs.c
+++ b/sys/dev/drm2/drm_bufs.c
@@ -1635,12 +1635,12 @@ int drm_mapbufs(struct drm_device *dev, void *data,
goto done;
}
retcode = vm_mmap(&vms->vm_map, &virtual, map->size,
- PROT_READ | PROT_WRITE, VM_PROT_ALL,
+ VM_PROT_READ | VM_PROT_WRITE, VM_PROT_ALL,
MAP_SHARED | MAP_NOSYNC, OBJT_DEVICE,
file_priv->minor->device, token);
} else {
retcode = vm_mmap(&vms->vm_map, &virtual, dma->byte_count,
- PROT_READ | PROT_WRITE, VM_PROT_ALL,
+ VM_PROT_READ | VM_PROT_WRITE, VM_PROT_ALL,
MAP_SHARED | MAP_NOSYNC, OBJT_DEVICE,
file_priv->minor->device, 0);
}
diff --git a/sys/dev/drm2/i915/i915_gem.c b/sys/dev/drm2/i915/i915_gem.c
index a47303155fab..356ccc5d80da 100644
--- a/sys/dev/drm2/i915/i915_gem.c
+++ b/sys/dev/drm2/i915/i915_gem.c
@@ -1874,7 +1874,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
map = &p->p_vmspace->vm_map;
size = round_page(args->size);
PROC_LOCK(p);
- if (map->size + size > lim_cur(p, RLIMIT_VMEM)) {
+ if (map->size + size > lim_cur_proc(p, RLIMIT_VMEM)) {
PROC_UNLOCK(p);
error = -ENOMEM;
goto out;
@@ -3175,9 +3175,6 @@ i915_gem_wire_page(vm_object_t object, vm_pindex_t pindex, bool *fresh)
if (m->valid != VM_PAGE_BITS_ALL) {
if (vm_pager_has_page(object, pindex, NULL, NULL)) {
rv = vm_pager_get_pages(object, &m, 1, 0);
- m = vm_page_lookup(object, pindex);
- if (m == NULL)
- return (NULL);
if (rv != VM_PAGER_OK) {
vm_page_lock(m);
vm_page_free(m);
diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c
index 57e6b44eee9e..7ca16ace8e09 100644
--- a/sys/dev/dwc/if_dwc.c
+++ b/sys/dev/dwc/if_dwc.c
@@ -741,9 +741,11 @@ dwc_txfinish_locked(struct dwc_softc *sc)
{
struct dwc_bufmap *bmap;
struct dwc_hwdesc *desc;
+ struct ifnet *ifp;
DWC_ASSERT_LOCKED(sc);
+ ifp = sc->ifp;
while (sc->tx_idx_tail != sc->tx_idx_head) {
desc = &sc->txdesc_ring[sc->tx_idx_tail];
if ((desc->tdes0 & DDESC_TDES0_OWN) != 0)
@@ -756,6 +758,7 @@ dwc_txfinish_locked(struct dwc_softc *sc)
bmap->mbuf = NULL;
dwc_setup_txdesc(sc, sc->tx_idx_tail, 0, 0);
sc->tx_idx_tail = next_txidx(sc, sc->tx_idx_tail);
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
/* If there are no buffers outstanding, muzzle the watchdog. */
@@ -838,8 +841,10 @@ dwc_intr(void *arg)
if (reg & DMA_STATUS_RI)
dwc_rxfinish_locked(sc);
- if (reg & DMA_STATUS_TI)
+ if (reg & DMA_STATUS_TI) {
dwc_txfinish_locked(sc);
+ dwc_txstart_locked(sc);
+ }
}
if (reg & DMA_STATUS_AIS) {
diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h
index 77589ed7cefe..5deada2a094b 100644
--- a/sys/dev/e1000/e1000_defines.h
+++ b/sys/dev/e1000/e1000_defines.h
@@ -158,10 +158,12 @@
E1000_RXDEXT_STATERR_CXE | \
E1000_RXDEXT_STATERR_RXE)
+#define E1000_MRQC_RSS_ENABLE_2Q 0x00000001
#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
+#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000
#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index ab39c4355782..8032345d09ae 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2014, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,8 @@
******************************************************************************/
/*$FreeBSD$*/
+#include "opt_em.h"
+#include "opt_ddb.h"
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -41,6 +43,10 @@
#include <sys/param.h>
#include <sys/systm.h>
+#ifdef DDB
+#include <sys/types.h>
+#include <ddb/ddb.h>
+#endif
#if __FreeBSD_version >= 800000
#include <sys/buf_ring.h>
#endif
@@ -52,6 +58,7 @@
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/rman.h>
+#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
@@ -208,7 +215,7 @@ static int em_resume(device_t);
#ifdef EM_MULTIQUEUE
static int em_mq_start(if_t, struct mbuf *);
static int em_mq_start_locked(if_t,
- struct tx_ring *, struct mbuf *);
+ struct tx_ring *);
static void em_qflush(if_t);
#else
static void em_start(if_t);
@@ -299,6 +306,10 @@ static void em_handle_tx(void *context, int pending);
static void em_handle_rx(void *context, int pending);
static void em_handle_link(void *context, int pending);
+#ifdef EM_MULTIQUEUE
+static void em_enable_vectors_82574(struct adapter *);
+#endif
+
static void em_set_sysctl_value(struct adapter *, const char *,
const char *, int *, int);
static int em_set_flowcntl(SYSCTL_HANDLER_ARGS);
@@ -388,6 +399,19 @@ static int em_enable_msix = TRUE;
SYSCTL_INT(_hw_em, OID_AUTO, enable_msix, CTLFLAG_RDTUN, &em_enable_msix, 0,
"Enable MSI-X interrupts");
+#ifdef EM_MULTIQUEUE
+static int em_num_queues = 1;
+SYSCTL_INT(_hw_em, OID_AUTO, num_queues, CTLFLAG_RDTUN, &em_num_queues, 0,
+ "82574 only: Number of queues to configure, 0 indicates autoconfigure");
+#endif
+
+/*
+** Global variable to store last used CPU when binding queues
+** to CPUs in igb_allocate_msix. Starts at CPU_FIRST and increments when a
+** queue is bound to a cpu.
+*/
+static int em_last_bind_cpu = -1;
+
/* How many packets rxeof tries to clean at a time */
static int em_rx_process_limit = 100;
SYSCTL_INT(_hw_em, OID_AUTO, rx_process_limit, CTLFLAG_RDTUN,
@@ -420,10 +444,10 @@ static int
em_probe(device_t dev)
{
char adapter_name[60];
- u16 pci_vendor_id = 0;
- u16 pci_device_id = 0;
- u16 pci_subvendor_id = 0;
- u16 pci_subdevice_id = 0;
+ uint16_t pci_vendor_id = 0;
+ uint16_t pci_device_id = 0;
+ uint16_t pci_subvendor_id = 0;
+ uint16_t pci_subdevice_id = 0;
em_vendor_info_t *ent;
INIT_DEBUGOUT("em_probe: begin");
@@ -550,6 +574,11 @@ em_attach(device_t dev)
goto err_pci;
}
+ /*
+ * Setup MSI/X or MSI if PCI Express
+ */
+ adapter->msix = em_setup_msix(adapter);
+
e1000_get_bus_info(hw);
/* Set up some sysctls for the tunable interrupt delays */
@@ -880,7 +909,7 @@ em_resume(device_t dev)
EM_TX_LOCK(txr);
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
- em_mq_start_locked(ifp, txr, NULL);
+ em_mq_start_locked(ifp, txr);
#else
if (!if_sendq_empty(ifp))
em_start_locked(ifp, txr);
@@ -894,107 +923,7 @@ em_resume(device_t dev)
}
-#ifdef EM_MULTIQUEUE
-/*********************************************************************
- * Multiqueue Transmit routines
- *
- * em_mq_start is called by the stack to initiate a transmit.
- * however, if busy the driver can queue the request rather
- * than do an immediate send. It is this that is an advantage
- * in this driver, rather than also having multiple tx queues.
- **********************************************************************/
-static int
-em_mq_start_locked(if_t ifp, struct tx_ring *txr, struct mbuf *m)
-{
- struct adapter *adapter = txr->adapter;
- struct mbuf *next;
- int err = 0, enq = 0;
-
- if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
- IFF_DRV_RUNNING || adapter->link_active == 0) {
- if (m != NULL)
- err = drbr_enqueue(ifp, txr->br, m);
- return (err);
- }
-
- enq = 0;
- if (m != NULL) {
- err = drbr_enqueue(ifp, txr->br, m);
- if (err)
- return (err);
- }
-
- /* Process the queue */
- while ((next = drbr_peek(ifp, txr->br)) != NULL) {
- if ((err = em_xmit(txr, &next)) != 0) {
- if (next == NULL)
- drbr_advance(ifp, txr->br);
- else
- drbr_putback(ifp, txr->br, next);
- break;
- }
- drbr_advance(ifp, txr->br);
- enq++;
- if_inc_counter(ifp, IFCOUNTER_OBYTES, next->m_pkthdr.len);
- if (next->m_flags & M_MCAST)
- if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
- if_etherbpfmtap(ifp, next);
- if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
- break;
- }
-
- if (enq > 0) {
- /* Set the watchdog */
- txr->queue_status = EM_QUEUE_WORKING;
- txr->watchdog_time = ticks;
- }
-
- if (txr->tx_avail < EM_MAX_SCATTER)
- em_txeof(txr);
- if (txr->tx_avail < EM_MAX_SCATTER)
- if_setdrvflagbits(ifp, IFF_DRV_OACTIVE,0);
- return (err);
-}
-
-/*
-** Multiqueue capable stack interface
-*/
-static int
-em_mq_start(if_t ifp, struct mbuf *m)
-{
- struct adapter *adapter = if_getsoftc(ifp);
- struct tx_ring *txr = adapter->tx_rings;
- int error;
-
- if (EM_TX_TRYLOCK(txr)) {
- error = em_mq_start_locked(ifp, txr, m);
- EM_TX_UNLOCK(txr);
- } else
- error = drbr_enqueue(ifp, txr->br, m);
-
- return (error);
-}
-
-/*
-** Flush all ring buffers
-*/
-static void
-em_qflush(if_t ifp)
-{
- struct adapter *adapter = if_getsoftc(ifp);
- struct tx_ring *txr = adapter->tx_rings;
- struct mbuf *m;
-
- for (int i = 0; i < adapter->num_queues; i++, txr++) {
- EM_TX_LOCK(txr);
- while ((m = buf_ring_dequeue_sc(txr->br)) != NULL)
- m_freem(m);
- EM_TX_UNLOCK(txr);
- }
- if_qflush(ifp);
-}
-#else /* !EM_MULTIQUEUE */
-
+#ifndef EM_MULTIQUEUE
static void
em_start_locked(if_t ifp, struct tx_ring *txr)
{
@@ -1032,12 +961,13 @@ em_start_locked(if_t ifp, struct tx_ring *txr)
break;
}
+ /* Mark the queue as having work */
+ if (txr->busy == EM_TX_IDLE)
+ txr->busy = EM_TX_BUSY;
+
/* Send a copy of the frame to the BPF listener */
- if_etherbpfmtap(ifp, m_head);
+ ETHER_BPF_MTAP(ifp, m_head);
- /* Set timeout in case hardware has problems transmitting. */
- txr->watchdog_time = ticks;
- txr->queue_status = EM_QUEUE_WORKING;
}
return;
@@ -1056,6 +986,115 @@ em_start(if_t ifp)
}
return;
}
+#else /* EM_MULTIQUEUE */
+/*********************************************************************
+ * Multiqueue Transmit routines
+ *
+ * em_mq_start is called by the stack to initiate a transmit.
+ * however, if busy the driver can queue the request rather
+ * than do an immediate send. It is this that is an advantage
+ * in this driver, rather than also having multiple tx queues.
+ **********************************************************************/
+/*
+** Multiqueue capable stack interface
+*/
+static int
+em_mq_start(if_t ifp, struct mbuf *m)
+{
+ struct adapter *adapter = if_getsoftc(ifp);
+ struct tx_ring *txr = adapter->tx_rings;
+ unsigned int i, error;
+
+ if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE)
+ i = m->m_pkthdr.flowid % adapter->num_queues;
+ else
+ i = curcpu % adapter->num_queues;
+
+ txr = &adapter->tx_rings[i];
+
+ error = drbr_enqueue(ifp, txr->br, m);
+ if (error)
+ return (error);
+
+ if (EM_TX_TRYLOCK(txr)) {
+ em_mq_start_locked(ifp, txr);
+ EM_TX_UNLOCK(txr);
+ } else
+ taskqueue_enqueue(txr->tq, &txr->tx_task);
+
+ return (0);
+}
+
+static int
+em_mq_start_locked(if_t ifp, struct tx_ring *txr)
+{
+ struct adapter *adapter = txr->adapter;
+ struct mbuf *next;
+ int err = 0, enq = 0;
+
+ EM_TX_LOCK_ASSERT(txr);
+
+ if (((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) ||
+ adapter->link_active == 0) {
+ return (ENETDOWN);
+ }
+
+ /* Process the queue */
+ while ((next = drbr_peek(ifp, txr->br)) != NULL) {
+ if ((err = em_xmit(txr, &next)) != 0) {
+ if (next == NULL) {
+ /* It was freed, move forward */
+ drbr_advance(ifp, txr->br);
+ } else {
+ /*
+ * Still have one left, it may not be
+ * the same since the transmit function
+ * may have changed it.
+ */
+ drbr_putback(ifp, txr->br, next);
+ }
+ break;
+ }
+ drbr_advance(ifp, txr->br);
+ enq++;
+ if_inc_counter(ifp, IFCOUNTER_OBYTES, next->m_pkthdr.len);
+ if (next->m_flags & M_MCAST)
+ if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
+ ETHER_BPF_MTAP(ifp, next);
+ if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
+ break;
+ }
+
+ /* Mark the queue as having work */
+ if ((enq > 0) && (txr->busy == EM_TX_IDLE))
+ txr->busy = EM_TX_BUSY;
+
+ if (txr->tx_avail < EM_MAX_SCATTER)
+ em_txeof(txr);
+ if (txr->tx_avail < EM_MAX_SCATTER) {
+ if_setdrvflagbits(ifp, IFF_DRV_OACTIVE,0);
+ }
+ return (err);
+}
+
+/*
+** Flush all ring buffers
+*/
+static void
+em_qflush(if_t ifp)
+{
+ struct adapter *adapter = if_getsoftc(ifp);
+ struct tx_ring *txr = adapter->tx_rings;
+ struct mbuf *m;
+
+ for (int i = 0; i < adapter->num_queues; i++, txr++) {
+ EM_TX_LOCK(txr);
+ while ((m = buf_ring_dequeue_sc(txr->br)) != NULL)
+ m_freem(m);
+ EM_TX_UNLOCK(txr);
+ }
+ if_qflush(ifp);
+}
#endif /* EM_MULTIQUEUE */
/*********************************************************************
@@ -1451,7 +1490,7 @@ em_poll(if_t ifp, enum poll_cmd cmd, int count)
em_txeof(txr);
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
- em_mq_start_locked(ifp, txr, NULL);
+ em_mq_start_locked(ifp, txr);
#else
if (!if_sendq_empty(ifp))
em_start_locked(ifp, txr);
@@ -1518,14 +1557,14 @@ em_handle_que(void *context, int pending)
struct tx_ring *txr = adapter->tx_rings;
struct rx_ring *rxr = adapter->rx_rings;
-
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
bool more = em_rxeof(rxr, adapter->rx_process_limit, NULL);
+
EM_TX_LOCK(txr);
em_txeof(txr);
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
- em_mq_start_locked(ifp, txr, NULL);
+ em_mq_start_locked(ifp, txr);
#else
if (!if_sendq_empty(ifp))
em_start_locked(ifp, txr);
@@ -1559,11 +1598,12 @@ em_msix_tx(void *arg)
em_txeof(txr);
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
- em_mq_start_locked(ifp, txr, NULL);
+ em_mq_start_locked(ifp, txr);
#else
if (!if_sendq_empty(ifp))
em_start_locked(ifp, txr);
#endif
+
/* Reenable this interrupt */
E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims);
EM_TX_UNLOCK(txr);
@@ -1589,9 +1629,10 @@ em_msix_rx(void *arg)
more = em_rxeof(rxr, adapter->rx_process_limit, NULL);
if (more)
taskqueue_enqueue(rxr->tq, &rxr->rx_task);
- else
+ else {
/* Reenable this interrupt */
E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims);
+ }
return;
}
@@ -1618,6 +1659,16 @@ em_msix_link(void *arg)
} else
E1000_WRITE_REG(&adapter->hw, E1000_IMS,
EM_MSIX_LINK | E1000_IMS_LSC);
+ /*
+ ** Because we must read the ICR for this interrupt
+ ** it may clear other causes using autoclear, for
+ ** this reason we simply create a soft interrupt
+ ** for all these vectors.
+ */
+ if (reg_icr) {
+ E1000_WRITE_REG(&adapter->hw,
+ E1000_ICS, adapter->ims);
+ }
return;
}
@@ -1631,9 +1682,10 @@ em_handle_rx(void *context, int pending)
more = em_rxeof(rxr, adapter->rx_process_limit, NULL);
if (more)
taskqueue_enqueue(rxr->tq, &rxr->rx_task);
- else
+ else {
/* Reenable this interrupt */
E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims);
+ }
}
static void
@@ -1647,7 +1699,7 @@ em_handle_tx(void *context, int pending)
em_txeof(txr);
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
- em_mq_start_locked(ifp, txr, NULL);
+ em_mq_start_locked(ifp, txr);
#else
if (!if_sendq_empty(ifp))
em_start_locked(ifp, txr);
@@ -1677,7 +1729,7 @@ em_handle_link(void *context, int pending)
EM_TX_LOCK(txr);
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
- em_mq_start_locked(ifp, txr, NULL);
+ em_mq_start_locked(ifp, txr);
#else
if (if_sendq_empty(ifp))
em_start_locked(ifp, txr);
@@ -2102,8 +2154,6 @@ retry:
*/
tx_buffer = &txr->tx_buffers[first];
tx_buffer->next_eop = last;
- /* Update the watchdog time early and often */
- txr->watchdog_time = ticks;
/*
* Advance the Transmit Descriptor Tail (TDT), this tells the E1000
@@ -2223,7 +2273,7 @@ em_local_timer(void *arg)
if_t ifp = adapter->ifp;
struct tx_ring *txr = adapter->tx_rings;
struct rx_ring *rxr = adapter->rx_rings;
- u32 trigger;
+ u32 trigger = 0;
EM_CORE_LOCK_ASSERT(adapter);
@@ -2236,9 +2286,11 @@ em_local_timer(void *arg)
e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
/* Mask to use in the irq trigger */
- if (adapter->msix_mem)
- trigger = rxr->ims;
- else
+ if (adapter->msix_mem) {
+ for (int i = 0; i < adapter->num_queues; i++, rxr++)
+ trigger |= rxr->ims;
+ rxr = adapter->rx_rings;
+ } else
trigger = E1000_ICS_RXDMT0;
/*
@@ -2247,15 +2299,15 @@ em_local_timer(void *arg)
** and the HUNG state will be static if set.
*/
for (int i = 0; i < adapter->num_queues; i++, txr++) {
- if ((txr->queue_status == EM_QUEUE_HUNG) &&
- (adapter->pause_frames == 0))
+ if (txr->busy == EM_TX_HUNG)
goto hung;
+ if (txr->busy >= EM_TX_MAXTRIES)
+ txr->busy = EM_TX_HUNG;
/* Schedule a TX tasklet if needed */
if (txr->tx_avail <= EM_MAX_SCATTER)
taskqueue_enqueue(txr->tq, &txr->tx_task);
}
- adapter->pause_frames = 0;
callout_reset(&adapter->timer, hz, em_local_timer, adapter);
#ifndef DEVICE_POLLING
/* Trigger an RX interrupt to guarantee mbuf refresh */
@@ -2264,17 +2316,11 @@ em_local_timer(void *arg)
return;
hung:
/* Looks like we're hung */
- device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
- device_printf(adapter->dev,
- "Queue(%d) tdh = %d, hw tdt = %d\n", txr->me,
- E1000_READ_REG(&adapter->hw, E1000_TDH(txr->me)),
- E1000_READ_REG(&adapter->hw, E1000_TDT(txr->me)));
- device_printf(adapter->dev,"TX(%d) desc avail = %d,"
- "Next TX to Clean = %d\n",
- txr->me, txr->tx_avail, txr->next_to_clean);
+ device_printf(adapter->dev, "Watchdog timeout Queue[%d]-- resetting\n",
+ txr->me);
+ em_print_debug_info(adapter);
if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING);
adapter->watchdog_events++;
- adapter->pause_frames = 0;
em_init_locked(adapter);
}
@@ -2324,7 +2370,7 @@ em_update_link_status(struct adapter *adapter)
(hw->mac.type == e1000_82572))) {
int tarc0;
tarc0 = E1000_READ_REG(hw, E1000_TARC(0));
- tarc0 &= ~SPEED_MODE_BIT;
+ tarc0 &= ~TARC_SPEED_MODE_BIT;
E1000_WRITE_REG(hw, E1000_TARC(0), tarc0);
}
if (bootverbose)
@@ -2343,9 +2389,9 @@ em_update_link_status(struct adapter *adapter)
if (bootverbose)
device_printf(dev, "Link is Down\n");
adapter->link_active = 0;
- /* Link down, disable watchdog */
+ /* Link down, disable hang detection */
for (int i = 0; i < adapter->num_queues; i++, txr++)
- txr->queue_status = EM_QUEUE_IDLE;
+ txr->busy = EM_TX_IDLE;
if_link_state_change(ifp, LINK_STATE_DOWN);
}
}
@@ -2376,10 +2422,10 @@ em_stop(void *arg)
/* Tell the stack that the interface is no longer active */
if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING);
- /* Unarm watchdog timer. */
+ /* Disarm Hang Detection. */
for (int i = 0; i < adapter->num_queues; i++, txr++) {
EM_TX_LOCK(txr);
- txr->queue_status = EM_QUEUE_IDLE;
+ txr->busy = EM_TX_IDLE;
EM_TX_UNLOCK(txr);
}
@@ -2440,14 +2486,6 @@ em_allocate_pci_resources(struct adapter *adapter)
rman_get_bushandle(adapter->memory);
adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle;
- /* Default to a single queue */
- adapter->num_queues = 1;
-
- /*
- * Setup MSI/X or MSI if PCI Express
- */
- adapter->msix = em_setup_msix(adapter);
-
adapter->hw.back = &adapter->osdep;
return (0);
@@ -2522,13 +2560,14 @@ em_allocate_msix(struct adapter *adapter)
struct tx_ring *txr = adapter->tx_rings;
struct rx_ring *rxr = adapter->rx_rings;
int error, rid, vector = 0;
+ int cpu_id = 0;
/* Make sure all interrupts are disabled */
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
/* First set up ring resources */
- for (int i = 0; i < adapter->num_queues; i++, txr++, rxr++) {
+ for (int i = 0; i < adapter->num_queues; i++, rxr++, vector++) {
/* RX ring */
rid = vector + 1;
@@ -2548,14 +2587,20 @@ em_allocate_msix(struct adapter *adapter)
return (error);
}
#if __FreeBSD_version >= 800504
- bus_describe_intr(dev, rxr->res, rxr->tag, "rx %d", i);
+ bus_describe_intr(dev, rxr->res, rxr->tag, "rx%d", i);
#endif
- rxr->msix = vector++; /* NOTE increment vector for TX */
+ rxr->msix = vector;
+
+ if (em_last_bind_cpu < 0)
+ em_last_bind_cpu = CPU_FIRST();
+ cpu_id = em_last_bind_cpu;
+ bus_bind_intr(dev, rxr->res, cpu_id);
+
TASK_INIT(&rxr->rx_task, 0, em_handle_rx, rxr);
rxr->tq = taskqueue_create_fast("em_rxq", M_NOWAIT,
taskqueue_thread_enqueue, &rxr->tq);
- taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq",
- device_get_nameunit(adapter->dev));
+ taskqueue_start_threads(&rxr->tq, 1, PI_NET, "%s rxq (cpuid %d)",
+ device_get_nameunit(adapter->dev), cpu_id);
/*
** Set the bit to enable interrupt
** in E1000_IMS -- bits 20 and 21
@@ -2563,8 +2608,13 @@ em_allocate_msix(struct adapter *adapter)
** NOTHING to do with the MSIX vector
*/
rxr->ims = 1 << (20 + i);
+ adapter->ims |= rxr->ims;
adapter->ivars |= (8 | rxr->msix) << (i * 4);
+ em_last_bind_cpu = CPU_NEXT(em_last_bind_cpu);
+ }
+
+ for (int i = 0; i < adapter->num_queues; i++, txr++, vector++) {
/* TX ring */
rid = vector + 1;
txr->res = bus_alloc_resource_any(dev,
@@ -2582,14 +2632,20 @@ em_allocate_msix(struct adapter *adapter)
return (error);
}
#if __FreeBSD_version >= 800504
- bus_describe_intr(dev, txr->res, txr->tag, "tx %d", i);
+ bus_describe_intr(dev, txr->res, txr->tag, "tx%d", i);
#endif
- txr->msix = vector++; /* Increment vector for next pass */
+ txr->msix = vector;
+
+ if (em_last_bind_cpu < 0)
+ em_last_bind_cpu = CPU_FIRST();
+ cpu_id = em_last_bind_cpu;
+ bus_bind_intr(dev, txr->res, cpu_id);
+
TASK_INIT(&txr->tx_task, 0, em_handle_tx, txr);
txr->tq = taskqueue_create_fast("em_txq", M_NOWAIT,
taskqueue_thread_enqueue, &txr->tq);
- taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq",
- device_get_nameunit(adapter->dev));
+ taskqueue_start_threads(&txr->tq, 1, PI_NET, "%s txq (cpuid %d)",
+ device_get_nameunit(adapter->dev), cpu_id);
/*
** Set the bit to enable interrupt
** in E1000_IMS -- bits 22 and 23
@@ -2597,13 +2653,16 @@ em_allocate_msix(struct adapter *adapter)
** NOTHING to do with the MSIX vector
*/
txr->ims = 1 << (22 + i);
+ adapter->ims |= txr->ims;
adapter->ivars |= (8 | txr->msix) << (8 + (i * 4));
+
+ em_last_bind_cpu = CPU_NEXT(em_last_bind_cpu);
}
/* Link interrupt */
- ++rid;
+ rid = vector + 1;
adapter->res = bus_alloc_resource_any(dev,
- SYS_RES_IRQ, &rid, RF_ACTIVE);
+ SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
if (!adapter->res) {
device_printf(dev,"Unable to allocate "
"bus resource: Link interrupt [%d]\n", rid);
@@ -2619,7 +2678,7 @@ em_allocate_msix(struct adapter *adapter)
return (error);
}
#if __FreeBSD_version >= 800504
- bus_describe_intr(dev, adapter->res, adapter->tag, "link");
+ bus_describe_intr(dev, adapter->res, adapter->tag, "link");
#endif
adapter->linkvec = vector;
adapter->ivars |= (8 | vector) << 16;
@@ -2643,9 +2702,8 @@ em_free_pci_resources(struct adapter *adapter)
*/
for (int i = 0; i < adapter->num_queues; i++) {
txr = &adapter->tx_rings[i];
- rxr = &adapter->rx_rings[i];
/* an early abort? */
- if ((txr == NULL) || (rxr == NULL))
+ if (txr == NULL)
break;
rid = txr->msix +1;
if (txr->tag != NULL) {
@@ -2655,6 +2713,11 @@ em_free_pci_resources(struct adapter *adapter)
if (txr->res != NULL)
bus_release_resource(dev, SYS_RES_IRQ,
rid, txr->res);
+
+ rxr = &adapter->rx_rings[i];
+ /* an early abort? */
+ if (rxr == NULL)
+ break;
rid = rxr->msix +1;
if (rxr->tag != NULL) {
bus_teardown_intr(dev, rxr->res, rxr->tag);
@@ -2704,14 +2767,19 @@ em_setup_msix(struct adapter *adapter)
device_t dev = adapter->dev;
int val;
+ /* Nearly always going to use one queue */
+ adapter->num_queues = 1;
+
/*
- ** Setup MSI/X for Hartwell: tests have shown
- ** use of two queues to be unstable, and to
- ** provide no great gain anyway, so we simply
- ** seperate the interrupts and use a single queue.
+ ** Try using MSI-X for Hartwell adapters
*/
if ((adapter->hw.mac.type == e1000_82574) &&
(em_enable_msix == TRUE)) {
+#ifdef EM_MULTIQUEUE
+ adapter->num_queues = (em_num_queues == 1) ? 1 : 2;
+ if (adapter->num_queues > 1)
+ em_enable_vectors_82574(adapter);
+#endif
/* Map the MSIX BAR */
int rid = PCIR_BAR(EM_MSIX_BAR);
adapter->msix_mem = bus_alloc_resource_any(dev,
@@ -2723,16 +2791,34 @@ em_setup_msix(struct adapter *adapter)
goto msi;
}
val = pci_msix_count(dev);
- /* We only need/want 3 vectors */
- if (val >= 3)
- val = 3;
- else {
- device_printf(adapter->dev,
- "MSIX: insufficient vectors, using MSI\n");
- goto msi;
+
+#ifdef EM_MULTIQUEUE
+ /* We need 5 vectors in the multiqueue case */
+ if (adapter->num_queues > 1 ) {
+ if (val >= 5)
+ val = 5;
+ else {
+ adapter->num_queues = 1;
+ device_printf(adapter->dev,
+ "Insufficient MSIX vectors for >1 queue, "
+ "using single queue...\n");
+ goto msix_one;
+ }
+ } else {
+msix_one:
+#endif
+ if (val >= 3)
+ val = 3;
+ else {
+ device_printf(adapter->dev,
+ "Insufficient MSIX vectors, using MSI\n");
+ goto msi;
+ }
+#ifdef EM_MULTIQUEUE
}
+#endif
- if ((pci_alloc_msix(dev, &val) == 0) && (val == 3)) {
+ if ((pci_alloc_msix(dev, &val) == 0)) {
device_printf(adapter->dev,
"Using MSIX interrupts "
"with %d vectors\n", val);
@@ -2753,7 +2839,7 @@ msi:
}
val = 1;
if (pci_alloc_msi(dev, &val) == 0) {
- device_printf(adapter->dev,"Using an MSI interrupt\n");
+ device_printf(adapter->dev, "Using an MSI interrupt\n");
return (val);
}
/* Should only happen due to manual configuration */
@@ -3358,7 +3444,7 @@ em_setup_transmit_ring(struct tx_ring *txr)
/* Set number of descriptors available */
txr->tx_avail = adapter->num_tx_desc;
- txr->queue_status = EM_QUEUE_IDLE;
+ txr->busy = EM_TX_IDLE;
/* Clear checksum offload context. */
txr->last_hw_offload = 0;
@@ -3398,7 +3484,7 @@ em_initialize_transmit_unit(struct adapter *adapter)
{
struct tx_ring *txr = adapter->tx_rings;
struct e1000_hw *hw = &adapter->hw;
- u32 tctl, tarc, tipg = 0;
+ u32 tctl, txdctl = 0, tarc, tipg = 0;
INIT_DEBUGOUT("em_initialize_transmit_unit: begin");
@@ -3419,7 +3505,16 @@ em_initialize_transmit_unit(struct adapter *adapter)
E1000_READ_REG(&adapter->hw, E1000_TDBAL(i)),
E1000_READ_REG(&adapter->hw, E1000_TDLEN(i)));
- txr->queue_status = EM_QUEUE_IDLE;
+ txr->busy = EM_TX_IDLE;
+ txdctl = 0; /* clear txdctl */
+ txdctl |= 0x1f; /* PTHRESH */
+ txdctl |= 1 << 8; /* HTHRESH */
+ txdctl |= 1 << 16;/* WTHRESH */
+ txdctl |= 1 << 22; /* Reserved bit 22 must always be 1 */
+ txdctl |= E1000_TXDCTL_GRAN;
+ txdctl |= 1 << 25; /* LWTHRESH */
+
+ E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl);
}
/* Set the default values for the Tx Inter Packet Gap timer */
@@ -3450,15 +3545,25 @@ em_initialize_transmit_unit(struct adapter *adapter)
if ((adapter->hw.mac.type == e1000_82571) ||
(adapter->hw.mac.type == e1000_82572)) {
tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
- tarc |= SPEED_MODE_BIT;
+ tarc |= TARC_SPEED_MODE_BIT;
E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
} else if (adapter->hw.mac.type == e1000_80003es2lan) {
+ /* errata: program both queues to unweighted RR */
tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
tarc |= 1;
E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(1));
tarc |= 1;
E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc);
+ } else if (adapter->hw.mac.type == e1000_82574) {
+ tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
+ tarc |= TARC_ERRATA_BIT;
+ if ( adapter->num_queues > 1) {
+ tarc |= (TARC_COMPENSATION_MODE | TARC_MQ_FIX);
+ E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
+ E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc);
+ } else
+ E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
}
adapter->txd_cmd = E1000_TXD_CMD_IFCS;
@@ -3802,9 +3907,9 @@ em_txeof(struct tx_ring *txr)
return;
#endif /* DEV_NETMAP */
- /* No work, make sure watchdog is off */
+ /* No work, make sure hang detection is disabled */
if (txr->tx_avail == adapter->num_tx_desc) {
- txr->queue_status = EM_QUEUE_IDLE;
+ txr->busy = EM_TX_IDLE;
return;
}
@@ -3847,7 +3952,6 @@ em_txeof(struct tx_ring *txr)
tx_buffer->m_head = NULL;
}
tx_buffer->next_eop = -1;
- txr->watchdog_time = ticks;
if (++first == adapter->num_tx_desc)
first = 0;
@@ -3872,14 +3976,16 @@ em_txeof(struct tx_ring *txr)
txr->next_to_clean = first;
/*
- ** Watchdog calculation, we know there's
- ** work outstanding or the first return
- ** would have been taken, so none processed
- ** for too long indicates a hang. local timer
- ** will examine this and do a reset if needed.
+ ** Hang detection: we know there's work outstanding
+ ** or the entry return would have been taken, so no
+ ** descriptor processed here indicates a potential hang.
+ ** The local timer will examine this and do a reset if needed.
*/
- if ((!processed) && ((ticks - txr->watchdog_time) > EM_WATCHDOG))
- txr->queue_status = EM_QUEUE_HUNG;
+ if (processed == 0) {
+ if (txr->busy != EM_TX_HUNG)
+ ++txr->busy;
+ } else /* At least one descriptor was cleaned */
+ txr->busy = EM_TX_BUSY; /* note this clears HUNG */
/*
* If we have a minimum free, clear IFF_DRV_OACTIVE
@@ -3888,13 +3994,13 @@ em_txeof(struct tx_ring *txr)
* TX lock which, with a single queue, guarantees
* sanity.
*/
- if (txr->tx_avail >= EM_MAX_SCATTER)
+ if (txr->tx_avail >= EM_MAX_SCATTER) {
if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
+ }
- /* Disable watchdog if all clean */
- if (txr->tx_avail == adapter->num_tx_desc) {
- txr->queue_status = EM_QUEUE_IDLE;
- }
+ /* Disable hang detection if all clean */
+ if (txr->tx_avail == adapter->num_tx_desc)
+ txr->busy = EM_TX_IDLE;
}
@@ -4262,6 +4368,9 @@ em_initialize_receive_unit(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_RADV,
adapter->rx_abs_int_delay.value);
+
+ E1000_WRITE_REG(&adapter->hw, E1000_RDTR,
+ adapter->rx_int_delay.value);
/*
* Set the interrupt throttling rate. Value is calculated
* as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns)
@@ -4273,20 +4382,65 @@ em_initialize_receive_unit(struct adapter *adapter)
** using the EITR register (82574 only)
*/
if (hw->mac.type == e1000_82574) {
+ u32 rfctl;
for (int i = 0; i < 4; i++)
E1000_WRITE_REG(hw, E1000_EITR_82574(i),
DEFAULT_ITR);
/* Disable accelerated acknowledge */
- E1000_WRITE_REG(hw, E1000_RFCTL, E1000_RFCTL_ACK_DIS);
+ rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+ rfctl |= E1000_RFCTL_ACK_DIS;
+ E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
}
rxcsum = E1000_READ_REG(hw, E1000_RXCSUM);
- if (if_getcapenable(ifp) & IFCAP_RXCSUM)
+ if (if_getcapenable(ifp) & IFCAP_RXCSUM) {
+#ifdef EM_MULTIQUEUE
+ rxcsum |= E1000_RXCSUM_TUOFL |
+ E1000_RXCSUM_IPOFL |
+ E1000_RXCSUM_PCSD;
+#else
rxcsum |= E1000_RXCSUM_TUOFL;
- else
+#endif
+ } else
rxcsum &= ~E1000_RXCSUM_TUOFL;
+
E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);
+#ifdef EM_MULTIQUEUE
+ if (adapter->num_queues > 1) {
+ uint32_t rss_key[10];
+ uint32_t reta;
+ int i;
+
+ /*
+ * Configure RSS key
+ */
+ arc4rand(rss_key, sizeof(rss_key), 0);
+ for (i = 0; i < 10; ++i)
+ E1000_WRITE_REG_ARRAY(hw,E1000_RSSRK(0), i, rss_key[i]);
+
+ /*
+ * Configure RSS redirect table in following fashion:
+ * (hash & ring_cnt_mask) == rdr_table[(hash & rdr_table_mask)]
+ */
+ reta = 0;
+ for (i = 0; i < 4; ++i) {
+ uint32_t q;
+ q = (i % adapter->num_queues) << 7;
+ reta |= q << (8 * i);
+ }
+ for (i = 0; i < 32; ++i)
+ E1000_WRITE_REG(hw, E1000_RETA(i), reta);
+
+ E1000_WRITE_REG(hw, E1000_MRQC, E1000_MRQC_RSS_ENABLE_2Q |
+ E1000_MRQC_RSS_FIELD_IPV4_TCP |
+ E1000_MRQC_RSS_FIELD_IPV4 |
+ E1000_MRQC_RSS_FIELD_IPV6_TCP_EX |
+ E1000_MRQC_RSS_FIELD_IPV6_EX |
+ E1000_MRQC_RSS_FIELD_IPV6 |
+ E1000_MRQC_RSS_FIELD_IPV6_TCP);
+ }
+#endif
/*
** XXX TEMPORARY WORKAROUND: on some systems with 82573
** long latencies are observed, like Lenovo X60. This
@@ -4321,13 +4475,30 @@ em_initialize_receive_unit(struct adapter *adapter)
E1000_WRITE_REG(hw, E1000_RDT(i), rdt);
}
- /* Set PTHRESH for improved jumbo performance */
+ /*
+ * Set PTHRESH for improved jumbo performance
+ * According to 10.2.5.11 of Intel 82574 Datasheet,
+ * RXDCTL(1) is written whenever RXDCTL(0) is written.
+ * Only write to RXDCTL(1) if there is a need for different
+ * settings.
+ */
if (((adapter->hw.mac.type == e1000_ich9lan) ||
(adapter->hw.mac.type == e1000_pch2lan) ||
(adapter->hw.mac.type == e1000_ich10lan)) &&
(if_getmtu(ifp) > ETHERMTU)) {
u32 rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(0));
E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl | 3);
+ } else if ((adapter->hw.mac.type == e1000_82574) &&
+ (if_getmtu(ifp) > ETHERMTU)) {
+ for (int i = 0; i < adapter->num_queues; i++) {
+ u32 rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(i));
+
+ rxdctl |= 0x20; /* PTHRESH */
+ rxdctl |= 4 << 8; /* HTHRESH */
+ rxdctl |= 4 << 16;/* WTHRESH */
+ rxdctl |= 1 << 24; /* Switch to granularity */
+ E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl);
+ }
}
if (adapter->hw.mac.type >= e1000_pch2lan) {
@@ -4394,6 +4565,11 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
EM_RX_LOCK(rxr);
+ /* Sync the ring */
+ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+
#ifdef DEV_NETMAP
if (netmap_rx_irq(ifp, rxr->me, &processed)) {
EM_RX_UNLOCK(rxr);
@@ -4406,9 +4582,6 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
break;
- bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-
cur = &rxr->rx_base[i];
status = cur->status;
mp = sendmp = NULL;
@@ -4474,6 +4647,10 @@ skip:
rxr->fmp = rxr->lmp = NULL;
}
next_desc:
+ /* Sync the ring */
+ bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
/* Zero out the receive descriptors status. */
cur->status = 0;
++rxdone; /* cumulative for POLL */
@@ -5130,12 +5307,7 @@ em_update_stats_counters(struct adapter *adapter)
adapter->stats.rlec += E1000_READ_REG(&adapter->hw, E1000_RLEC);
adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, E1000_XONRXC);
adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, E1000_XONTXC);
- /*
- ** For watchdog management we need to know if we have been
- ** paused during the last interval, so capture that here.
- */
- adapter->pause_frames = E1000_READ_REG(&adapter->hw, E1000_XOFFRXC);
- adapter->stats.xoffrxc += adapter->pause_frames;
+ adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, E1000_XOFFRXC);
adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC);
adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC);
adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64);
@@ -5300,10 +5472,10 @@ em_add_hw_stats(struct adapter *adapter)
CTLFLAG_RD, &adapter->hw.fc.low_water, 0,
"Flow Control Low Watermark");
- for (int i = 0; i < adapter->num_queues; i++, rxr++, txr++) {
- snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i);
+ for (int i = 0; i < adapter->num_queues; i++, txr++, rxr++) {
+ snprintf(namebuf, QUEUE_NAME_LEN, "queue_tx_%d", i);
queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
- CTLFLAG_RD, NULL, "Queue Name");
+ CTLFLAG_RD, NULL, "TX Queue Name");
queue_list = SYSCTL_CHILDREN(queue_node);
SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head",
@@ -5322,7 +5494,12 @@ em_add_hw_stats(struct adapter *adapter)
SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "no_desc_avail",
CTLFLAG_RD, &txr->no_desc_avail,
"Queue No Descriptor Available");
-
+
+ snprintf(namebuf, QUEUE_NAME_LEN, "queue_rx_%d", i);
+ queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
+ CTLFLAG_RD, NULL, "RX Queue Name");
+ queue_list = SYSCTL_CHILDREN(queue_node);
+
SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_head",
CTLTYPE_UINT | CTLFLAG_RD, adapter,
E1000_RDH(rxr->me),
@@ -5756,19 +5933,86 @@ em_print_debug_info(struct adapter *adapter)
else
printf("and ACTIVE\n");
- device_printf(dev, "hw tdh = %d, hw tdt = %d\n",
- E1000_READ_REG(&adapter->hw, E1000_TDH(0)),
- E1000_READ_REG(&adapter->hw, E1000_TDT(0)));
- device_printf(dev, "hw rdh = %d, hw rdt = %d\n",
- E1000_READ_REG(&adapter->hw, E1000_RDH(0)),
- E1000_READ_REG(&adapter->hw, E1000_RDT(0)));
- device_printf(dev, "Tx Queue Status = %d\n", txr->queue_status);
- device_printf(dev, "TX descriptors avail = %d\n",
- txr->tx_avail);
- device_printf(dev, "Tx Descriptors avail failure = %ld\n",
- txr->no_desc_avail);
- device_printf(dev, "RX discarded packets = %ld\n",
- rxr->rx_discarded);
- device_printf(dev, "RX Next to Check = %d\n", rxr->next_to_check);
- device_printf(dev, "RX Next to Refresh = %d\n", rxr->next_to_refresh);
+ for (int i = 0; i < adapter->num_queues; i++, txr++, rxr++) {
+ device_printf(dev, "TX Queue %d ------\n", i);
+ device_printf(dev, "hw tdh = %d, hw tdt = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_TDH(i)),
+ E1000_READ_REG(&adapter->hw, E1000_TDT(i)));
+ device_printf(dev, "Tx Queue Status = %d\n", txr->busy);
+ device_printf(dev, "TX descriptors avail = %d\n",
+ txr->tx_avail);
+ device_printf(dev, "Tx Descriptors avail failure = %ld\n",
+ txr->no_desc_avail);
+ device_printf(dev, "RX Queue %d ------\n", i);
+ device_printf(dev, "hw rdh = %d, hw rdt = %d\n",
+ E1000_READ_REG(&adapter->hw, E1000_RDH(i)),
+ E1000_READ_REG(&adapter->hw, E1000_RDT(i)));
+ device_printf(dev, "RX discarded packets = %ld\n",
+ rxr->rx_discarded);
+ device_printf(dev, "RX Next to Check = %d\n", rxr->next_to_check);
+ device_printf(dev, "RX Next to Refresh = %d\n", rxr->next_to_refresh);
+ }
+}
+
+#ifdef EM_MULTIQUEUE
+/*
+ * 82574 only:
+ * Write a new value to the EEPROM increasing the number of MSIX
+ * vectors from 3 to 5, for proper multiqueue support.
+ */
+static void
+em_enable_vectors_82574(struct adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ device_t dev = adapter->dev;
+ u16 edata;
+
+ e1000_read_nvm(hw, EM_NVM_PCIE_CTRL, 1, &edata);
+ printf("Current cap: %#06x\n", edata);
+ if (((edata & EM_NVM_MSIX_N_MASK) >> EM_NVM_MSIX_N_SHIFT) != 4) {
+ device_printf(dev, "Writing to eeprom: increasing "
+ "reported MSIX vectors from 3 to 5...\n");
+ edata &= ~(EM_NVM_MSIX_N_MASK);
+ edata |= 4 << EM_NVM_MSIX_N_SHIFT;
+ e1000_write_nvm(hw, EM_NVM_PCIE_CTRL, 1, &edata);
+ e1000_update_nvm_checksum(hw);
+ device_printf(dev, "Writing to eeprom: done\n");
+ }
+}
+#endif
+
+#ifdef DDB
+DB_COMMAND(em_reset_dev, em_ddb_reset_dev)
+{
+ devclass_t dc;
+ int max_em;
+
+ dc = devclass_find("em");
+ max_em = devclass_get_maxunit(dc);
+
+ for (int index = 0; index < (max_em - 1); index++) {
+ device_t dev;
+ dev = devclass_get_device(dc, index);
+ if (device_get_driver(dev) == &em_driver) {
+ struct adapter *adapter = device_get_softc(dev);
+ em_init_locked(adapter);
+ }
+ }
+}
+DB_COMMAND(em_dump_queue, em_ddb_dump_queue)
+{
+ devclass_t dc;
+ int max_em;
+
+ dc = devclass_find("em");
+ max_em = devclass_get_maxunit(dc);
+
+ for (int index = 0; index < (max_em - 1); index++) {
+ device_t dev;
+ dev = devclass_get_device(dc, index);
+ if (device_get_driver(dev) == &em_driver)
+ em_print_debug_info(device_get_softc(dev));
+ }
+
}
+#endif
diff --git a/sys/dev/e1000/if_em.h b/sys/dev/e1000/if_em.h
index a73981561ed4..be18a6c9af94 100644
--- a/sys/dev/e1000/if_em.h
+++ b/sys/dev/e1000/if_em.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2011, Intel Corporation
+ Copyright (c) 2001-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -53,7 +53,11 @@
*/
#define EM_MIN_TXD 80
#define EM_MAX_TXD 4096
+#ifdef EM_MULTIQUEUE
+#define EM_DEFAULT_TXD 4096
+#else
#define EM_DEFAULT_TXD 1024
+#endif
/*
* EM_RXD - Maximum number of receive Descriptors
@@ -70,7 +74,11 @@
*/
#define EM_MIN_RXD 80
#define EM_MAX_RXD 4096
+#ifdef EM_MULTIQUEUE
+#define EM_DEFAULT_RXD 4096
+#else
#define EM_DEFAULT_RXD 1024
+#endif
/*
* EM_TIDV - Transmit Interrupt Delay Value
@@ -117,7 +125,11 @@
* restoring the network connection. To eliminate the potential
* for the hang ensure that EM_RDTR is set to 0.
*/
+#ifdef EM_MULTIQUEUE
+#define EM_RDTR 64
+#else
#define EM_RDTR 0
+#endif
/*
* Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
@@ -130,7 +142,11 @@
* along with EM_RDTR, may improve traffic throughput in specific network
* conditions.
*/
+#ifdef EM_MULTIQUEUE
+#define EM_RADV 128
+#else
#define EM_RADV 64
+#endif
/*
* This parameter controls the max duration of transmit watchdog.
@@ -188,9 +204,19 @@
#define EM_EEPROM_APME 0x400;
#define EM_82544_APME 0x0004;
-#define EM_QUEUE_IDLE 0
-#define EM_QUEUE_WORKING 1
-#define EM_QUEUE_HUNG 2
+/*
+ * Driver state logic for the detection of a hung state
+ * in hardware. Set TX_HUNG whenever a TX packet is used
+ * (data is sent) and clear it when txeof() is invoked if
+ * any descriptors from the ring are cleaned/reclaimed.
+ * Increment internal counter if no descriptors are cleaned
+ * and compare to TX_MAXTRIES. When counter > TX_MAXTRIES,
+ * reset adapter.
+ */
+#define EM_TX_IDLE 0x00000000
+#define EM_TX_BUSY 0x00000001
+#define EM_TX_HUNG 0x80000000
+#define EM_TX_MAXTRIES 10
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
@@ -199,7 +225,15 @@
*/
#define EM_DBA_ALIGN 128
-#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */
+/*
+ * See Intel 82574 Driver Programming Interface Manual, Section 10.2.6.9
+ */
+#define TARC_COMPENSATION_MODE (1 << 7) /* Compensation Mode */
+#define TARC_SPEED_MODE_BIT (1 << 21) /* On PCI-E MACs only */
+#define TARC_MQ_FIX (1 << 23) | \
+ (1 << 24) | \
+ (1 << 25) /* Handle errata in MQ mode */
+#define TARC_ERRATA_BIT (1 << 26) /* Note from errata on 82574 */
/* PCI Config defines */
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
@@ -249,6 +283,14 @@
* solve it just using this define.
*/
#define EM_EIAC 0x000DC
+/*
+ * 82574 only reports 3 MSI-X vectors by default;
+ * defines assisting with making it report 5 are
+ * located here.
+ */
+#define EM_NVM_PCIE_CTRL 0x1B
+#define EM_NVM_MSIX_N_MASK (0x7 << EM_NVM_MSIX_N_SHIFT)
+#define EM_NVM_MSIX_N_SHIFT 7
/*
* Bus dma allocation structure used by
@@ -281,8 +323,7 @@ struct tx_ring {
u32 me;
u32 msix;
u32 ims;
- int queue_status;
- int watchdog_time;
+ int busy;
struct em_dma_alloc txdma;
struct e1000_tx_desc *tx_base;
struct task tx_task;
@@ -368,7 +409,6 @@ struct adapter {
int if_flags;
int max_frame_size;
int min_frame_size;
- int pause_frames;
struct mtx core_mtx;
int em_insert_vlan_header;
u32 ims;
@@ -383,7 +423,7 @@ struct adapter {
eventhandler_tag vlan_detach;
u16 num_vlans;
- u16 num_queues;
+ u8 num_queues;
/*
* Transmit rings:
diff --git a/sys/dev/fdt/fdt_common.c b/sys/dev/fdt/fdt_common.c
index 0198d550ca2c..f00519e5646f 100644
--- a/sys/dev/fdt/fdt_common.c
+++ b/sys/dev/fdt/fdt_common.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#define FDT_COMPAT_LEN 255
#define FDT_TYPE_LEN 64
-#define FDT_NAME_LEN 32
#define FDT_REG_CELLS 4
@@ -311,22 +310,6 @@ fdt_find_compatible(phandle_t start, const char *compat, int strict)
}
phandle_t
-fdt_find_child(phandle_t start, const char *child_name)
-{
- char name[FDT_NAME_LEN];
- phandle_t child;
-
- for (child = OF_child(start); child != 0; child = OF_peer(child)) {
- if (OF_getprop(child, "name", name, sizeof(name)) <= 0)
- continue;
- if (strcmp(name, child_name) == 0)
- return (child);
- }
-
- return (0);
-}
-
-phandle_t
fdt_depth_search_compatible(phandle_t start, const char *compat, int strict)
{
phandle_t child, node;
diff --git a/sys/dev/fdt/fdt_common.h b/sys/dev/fdt/fdt_common.h
index 68012978ac26..3d05341dad1d 100644
--- a/sys/dev/fdt/fdt_common.h
+++ b/sys/dev/fdt/fdt_common.h
@@ -81,7 +81,6 @@ u_long fdt_data_get(void *, int);
int fdt_data_to_res(pcell_t *, int, int, u_long *, u_long *);
phandle_t fdt_find_compatible(phandle_t, const char *, int);
phandle_t fdt_depth_search_compatible(phandle_t, const char *, int);
-phandle_t fdt_find_child(phandle_t, const char *);
int fdt_get_mem_regions(struct mem_region *, int *, uint32_t *);
int fdt_get_reserved_regions(struct mem_region *, int *);
int fdt_get_phyaddr(phandle_t, device_t, int *, void **);
diff --git a/sys/dev/gpio/gpioled.c b/sys/dev/gpio/gpioled.c
index 5af73735ffb4..01710c2e8f56 100644
--- a/sys/dev/gpio/gpioled.c
+++ b/sys/dev/gpio/gpioled.c
@@ -166,8 +166,10 @@ static int
gpioled_attach(device_t dev)
{
struct gpioled_softc *sc;
+ int state;
#ifdef FDT
phandle_t node;
+ char *default_state;
char *name;
#else
const char *name;
@@ -177,10 +179,29 @@ gpioled_attach(device_t dev)
sc->sc_dev = dev;
sc->sc_busdev = device_get_parent(dev);
GPIOLED_LOCK_INIT(sc);
+
+ state = 0;
+
#ifdef FDT
- name = NULL;
if ((node = ofw_bus_get_node(dev)) == -1)
return (ENXIO);
+
+ if (OF_getprop_alloc(node, "default-state",
+ sizeof(char), (void **)&default_state) != -1) {
+ if (strcasecmp(default_state, "on") == 0)
+ state = 1;
+ else if (strcasecmp(default_state, "off") == 0)
+ state = 0;
+ else if (strcasecmp(default_state, "keep") == 0)
+ state = -1;
+ else {
+ device_printf(dev,
+ "unknown value for default-state in FDT\n");
+ }
+ free(default_state, M_OFWPROP);
+ }
+
+ name = NULL;
if (OF_getprop_alloc(node, "label", 1, (void **)&name) == -1)
OF_getprop_alloc(node, "name", 1, (void **)&name);
#else
@@ -189,8 +210,8 @@ gpioled_attach(device_t dev)
name = NULL;
#endif
- sc->sc_leddev = led_create(gpioled_control, sc, name ? name :
- device_get_nameunit(dev));
+ sc->sc_leddev = led_create_state(gpioled_control, sc, name ? name :
+ device_get_nameunit(dev), state);
#ifdef FDT
if (name != NULL)
free(name, M_OFWPROP);
diff --git a/sys/dev/hwpmc/hwpmc_armv7.c b/sys/dev/hwpmc/hwpmc_armv7.c
index 66d49715c8b6..469eca8d22ac 100644
--- a/sys/dev/hwpmc/hwpmc_armv7.c
+++ b/sys/dev/hwpmc/hwpmc_armv7.c
@@ -39,9 +39,6 @@ __FBSDID("$FreeBSD$");
#include <machine/pmc_mdep.h>
#include <machine/cpu.h>
-#define CPU_ID_CORTEX_VER_MASK 0xff
-#define CPU_ID_CORTEX_VER_SHIFT 4
-
static int armv7_npmcs;
struct armv7_event_code_map {
@@ -49,49 +46,11 @@ struct armv7_event_code_map {
uint8_t pe_code;
};
-const struct armv7_event_code_map armv7_event_codes[] = {
- { PMC_EV_ARMV7_PMNC_SW_INCR, 0x00 },
- { PMC_EV_ARMV7_L1_ICACHE_REFILL, 0x01 },
- { PMC_EV_ARMV7_ITLB_REFILL, 0x02 },
- { PMC_EV_ARMV7_L1_DCACHE_REFILL, 0x03 },
- { PMC_EV_ARMV7_L1_DCACHE_ACCESS, 0x04 },
- { PMC_EV_ARMV7_DTLB_REFILL, 0x05 },
- { PMC_EV_ARMV7_MEM_READ, 0x06 },
- { PMC_EV_ARMV7_MEM_WRITE, 0x07 },
- { PMC_EV_ARMV7_INSTR_EXECUTED, 0x08 },
- { PMC_EV_ARMV7_EXC_TAKEN, 0x09 },
- { PMC_EV_ARMV7_EXC_EXECUTED, 0x0A },
- { PMC_EV_ARMV7_CID_WRITE, 0x0B },
- { PMC_EV_ARMV7_PC_WRITE, 0x0C },
- { PMC_EV_ARMV7_PC_IMM_BRANCH, 0x0D },
- { PMC_EV_ARMV7_PC_PROC_RETURN, 0x0E },
- { PMC_EV_ARMV7_MEM_UNALIGNED_ACCESS, 0x0F },
- { PMC_EV_ARMV7_PC_BRANCH_MIS_PRED, 0x10 },
- { PMC_EV_ARMV7_CLOCK_CYCLES, 0x11 },
- { PMC_EV_ARMV7_PC_BRANCH_PRED, 0x12 },
- { PMC_EV_ARMV7_MEM_ACCESS, 0x13 },
- { PMC_EV_ARMV7_L1_ICACHE_ACCESS, 0x14 },
- { PMC_EV_ARMV7_L1_DCACHE_WB, 0x15 },
- { PMC_EV_ARMV7_L2_CACHE_ACCESS, 0x16 },
- { PMC_EV_ARMV7_L2_CACHE_REFILL, 0x17 },
- { PMC_EV_ARMV7_L2_CACHE_WB, 0x18 },
- { PMC_EV_ARMV7_BUS_ACCESS, 0x19 },
- { PMC_EV_ARMV7_MEM_ERROR, 0x1A },
- { PMC_EV_ARMV7_INSTR_SPEC, 0x1B },
- { PMC_EV_ARMV7_TTBR_WRITE, 0x1C },
- { PMC_EV_ARMV7_BUS_CYCLES, 0x1D },
- { PMC_EV_ARMV7_CPU_CYCLES, 0xFF },
-};
-
-const int armv7_event_codes_size =
- sizeof(armv7_event_codes) / sizeof(armv7_event_codes[0]);
-
/*
* Per-processor information.
*/
struct armv7_cpu {
struct pmc_hw *pc_armv7pmcs;
- int cortex_ver;
};
static struct armv7_cpu **armv7_pcpu;
@@ -173,10 +132,10 @@ static int
armv7_allocate_pmc(int cpu, int ri, struct pmc *pm,
const struct pmc_op_pmcallocate *a)
{
- uint32_t caps, config;
struct armv7_cpu *pac;
enum pmc_event pe;
- int i;
+ uint32_t config;
+ uint32_t caps;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[armv7,%d] illegal CPU value %d", __LINE__, cpu));
@@ -190,18 +149,10 @@ armv7_allocate_pmc(int cpu, int ri, struct pmc *pm,
return (EINVAL);
pe = a->pm_ev;
- for (i = 0; i < armv7_event_codes_size; i++) {
- if (armv7_event_codes[i].pe_ev == pe) {
- config = armv7_event_codes[i].pe_code;
- break;
- }
- }
- if (i == armv7_event_codes_size)
- return EINVAL;
-
+ config = (pe & EVENT_ID_MASK);
pm->pm_md.pm_armv7.pm_armv7_evsel = config;
- PMCDBG2(MDP,ALL,2,"armv7-allocate ri=%d -> config=0x%x", ri, config);
+ PMCDBG2(MDP, ALL, 2, "armv7-allocate ri=%d -> config=0x%x", ri, config);
return 0;
}
@@ -225,7 +176,7 @@ armv7_read_pmc(int cpu, int ri, pmc_value_t *v)
else
tmp = armv7_pmcn_read(ri);
- PMCDBG2(MDP,REA,2,"armv7-read id=%d -> %jd", ri, tmp);
+ PMCDBG2(MDP, REA, 2, "armv7-read id=%d -> %jd", ri, tmp);
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
*v = ARMV7_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp);
else
@@ -249,7 +200,7 @@ armv7_write_pmc(int cpu, int ri, pmc_value_t v)
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = ARMV7_RELOAD_COUNT_TO_PERFCTR_VALUE(v);
- PMCDBG3(MDP,WRI,1,"armv7-write cpu=%d ri=%d v=%jx", cpu, ri, v);
+ PMCDBG3(MDP, WRI, 1, "armv7-write cpu=%d ri=%d v=%jx", cpu, ri, v);
if (pm->pm_md.pm_armv7.pm_armv7_evsel == 0xFF)
cp15_pmccntr_set(v);
@@ -264,7 +215,7 @@ armv7_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
- PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
+ PMCDBG3(MDP, CFG, 1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[armv7,%d] illegal CPU value %d", __LINE__, cpu));
@@ -457,20 +408,15 @@ armv7_pcpu_init(struct pmc_mdep *md, int cpu)
struct pmc_cpu *pc;
uint32_t pmnc;
int first_ri;
- int cpuid;
int i;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[armv7,%d] wrong cpu number %d", __LINE__, cpu));
- PMCDBG1(MDP,INI,1,"armv7-init cpu=%d", cpu);
+ PMCDBG1(MDP, INI, 1, "armv7-init cpu=%d", cpu);
armv7_pcpu[cpu] = pac = malloc(sizeof(struct armv7_cpu), M_PMC,
M_WAITOK|M_ZERO);
- cpuid = cpu_ident();
- pac->cortex_ver = (cpuid >> CPU_ID_CORTEX_VER_SHIFT) & \
- CPU_ID_CORTEX_VER_MASK;
-
pac->pc_armv7pmcs = malloc(sizeof(struct pmc_hw) * armv7_npmcs,
M_PMC, M_WAITOK|M_ZERO);
pc = pmc_pcpu[cpu];
@@ -509,14 +455,15 @@ pmc_armv7_initialize()
{
struct pmc_mdep *pmc_mdep;
struct pmc_classdep *pcd;
+ int idcode;
int reg;
reg = cp15_pmcr_get();
-
armv7_npmcs = (reg >> ARMV7_PMNC_N_SHIFT) & \
ARMV7_PMNC_N_MASK;
+ idcode = (reg & ARMV7_IDCODE_MASK) >> ARMV7_IDCODE_SHIFT;
- PMCDBG1(MDP,INI,1,"armv7-init npmcs=%d", armv7_npmcs);
+ PMCDBG1(MDP, INI, 1, "armv7-init npmcs=%d", armv7_npmcs);
/*
* Allocate space for pointers to PMC HW descriptors and for
@@ -527,7 +474,20 @@ pmc_armv7_initialize()
/* Just one class */
pmc_mdep = pmc_mdep_alloc(1);
- pmc_mdep->pmd_cputype = PMC_CPU_ARMV7;
+
+ switch (idcode) {
+ case ARMV7_IDCODE_CORTEX_A9:
+ pmc_mdep->pmd_cputype = PMC_CPU_ARMV7_CORTEX_A9;
+ break;
+ default:
+ case ARMV7_IDCODE_CORTEX_A8:
+ /*
+ * On A8 we implemented common events only,
+ * so use it for the rest of machines.
+ */
+ pmc_mdep->pmd_cputype = PMC_CPU_ARMV7_CORTEX_A8;
+ break;
+ }
pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_ARMV7];
pcd->pcd_caps = ARMV7_PMC_CAPS;
diff --git a/sys/dev/hwpmc/hwpmc_armv7.h b/sys/dev/hwpmc/hwpmc_armv7.h
index 35f7d5b5b364..5282345f99b4 100644
--- a/sys/dev/hwpmc/hwpmc_armv7.h
+++ b/sys/dev/hwpmc/hwpmc_armv7.h
@@ -48,9 +48,14 @@
#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters implemented */
#define ARMV7_PMNC_N_MASK 0x1f
#define ARMV7_PMNC_MASK 0x3f /* Writable bits */
+#define ARMV7_IDCODE_SHIFT 16 /* Identification code */
+#define ARMV7_IDCODE_MASK (0xff << ARMV7_IDCODE_SHIFT)
+#define ARMV7_IDCODE_CORTEX_A9 9
+#define ARMV7_IDCODE_CORTEX_A8 8
#define ARMV7_RELOAD_COUNT_TO_PERFCTR_VALUE(R) (-(R))
#define ARMV7_PERFCTR_VALUE_TO_RELOAD_COUNT(P) (-(P))
+#define EVENT_ID_MASK 0xFF
#ifdef _KERNEL
/* MD extension for 'struct pmc' */
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index d1b56f10835c..131eb3575e24 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -1655,7 +1655,8 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
continue;
}
- if (lobj->type != OBJT_VNODE || lobj->handle == NULL) {
+ vp = vm_object_vnode(lobj);
+ if (vp == NULL) {
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
VM_OBJECT_RUNLOCK(obj);
@@ -1667,7 +1668,7 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
* vnode, so we don't emit redundant MAP-IN
* directives.
*/
- if (entry->start == last_end && lobj->handle == last_vp) {
+ if (entry->start == last_end && vp == last_vp) {
last_end = entry->end;
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
@@ -1690,7 +1691,6 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p)
last_timestamp = map->timestamp;
vm_map_unlock_read(map);
- vp = lobj->handle;
vref(vp);
if (lobj != obj)
VM_OBJECT_RUNLOCK(lobj);
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
index 467367f57848..96dc9003f78d 100644
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -4766,41 +4766,342 @@ __PMC_EV_ALIAS("IMPC_C0H_TRK_REQUEST.ALL", UCP_EVENT_84H_01H)
* ARMv7 Events
*/
-#define __PMC_EV_ARMV7() \
- __PMC_EV(ARMV7, PMNC_SW_INCR) \
- __PMC_EV(ARMV7, L1_ICACHE_REFILL) \
- __PMC_EV(ARMV7, ITLB_REFILL) \
- __PMC_EV(ARMV7, L1_DCACHE_REFILL) \
- __PMC_EV(ARMV7, L1_DCACHE_ACCESS) \
- __PMC_EV(ARMV7, DTLB_REFILL) \
- __PMC_EV(ARMV7, MEM_READ) \
- __PMC_EV(ARMV7, MEM_WRITE) \
- __PMC_EV(ARMV7, INSTR_EXECUTED) \
- __PMC_EV(ARMV7, EXC_TAKEN) \
- __PMC_EV(ARMV7, EXC_EXECUTED) \
- __PMC_EV(ARMV7, CID_WRITE) \
- __PMC_EV(ARMV7, PC_WRITE) \
- __PMC_EV(ARMV7, PC_IMM_BRANCH) \
- __PMC_EV(ARMV7, PC_PROC_RETURN) \
- __PMC_EV(ARMV7, MEM_UNALIGNED_ACCESS) \
- __PMC_EV(ARMV7, PC_BRANCH_MIS_PRED) \
- __PMC_EV(ARMV7, CLOCK_CYCLES) \
- __PMC_EV(ARMV7, PC_BRANCH_PRED) \
- __PMC_EV(ARMV7, MEM_ACCESS) \
- __PMC_EV(ARMV7, L1_ICACHE_ACCESS) \
- __PMC_EV(ARMV7, L1_DCACHE_WB) \
- __PMC_EV(ARMV7, L2_CACHE_ACCESS) \
- __PMC_EV(ARMV7, L2_CACHE_REFILL) \
- __PMC_EV(ARMV7, L2_CACHE_WB) \
- __PMC_EV(ARMV7, BUS_ACCESS) \
- __PMC_EV(ARMV7, MEM_ERROR) \
- __PMC_EV(ARMV7, INSTR_SPEC) \
- __PMC_EV(ARMV7, TTBR_WRITE) \
- __PMC_EV(ARMV7, BUS_CYCLES) \
- __PMC_EV(ARMV7, CPU_CYCLES)
+#define __PMC_EV_ARMV7() \
+ __PMC_EV(ARMV7, EVENT_00H) \
+ __PMC_EV(ARMV7, EVENT_01H) \
+ __PMC_EV(ARMV7, EVENT_02H) \
+ __PMC_EV(ARMV7, EVENT_03H) \
+ __PMC_EV(ARMV7, EVENT_04H) \
+ __PMC_EV(ARMV7, EVENT_05H) \
+ __PMC_EV(ARMV7, EVENT_06H) \
+ __PMC_EV(ARMV7, EVENT_07H) \
+ __PMC_EV(ARMV7, EVENT_08H) \
+ __PMC_EV(ARMV7, EVENT_09H) \
+ __PMC_EV(ARMV7, EVENT_0AH) \
+ __PMC_EV(ARMV7, EVENT_0BH) \
+ __PMC_EV(ARMV7, EVENT_0CH) \
+ __PMC_EV(ARMV7, EVENT_0DH) \
+ __PMC_EV(ARMV7, EVENT_0EH) \
+ __PMC_EV(ARMV7, EVENT_0FH) \
+ __PMC_EV(ARMV7, EVENT_10H) \
+ __PMC_EV(ARMV7, EVENT_11H) \
+ __PMC_EV(ARMV7, EVENT_12H) \
+ __PMC_EV(ARMV7, EVENT_13H) \
+ __PMC_EV(ARMV7, EVENT_14H) \
+ __PMC_EV(ARMV7, EVENT_15H) \
+ __PMC_EV(ARMV7, EVENT_16H) \
+ __PMC_EV(ARMV7, EVENT_17H) \
+ __PMC_EV(ARMV7, EVENT_18H) \
+ __PMC_EV(ARMV7, EVENT_19H) \
+ __PMC_EV(ARMV7, EVENT_1AH) \
+ __PMC_EV(ARMV7, EVENT_1BH) \
+ __PMC_EV(ARMV7, EVENT_1CH) \
+ __PMC_EV(ARMV7, EVENT_1DH) \
+ __PMC_EV(ARMV7, EVENT_1EH) \
+ __PMC_EV(ARMV7, EVENT_1FH) \
+ __PMC_EV(ARMV7, EVENT_20H) \
+ __PMC_EV(ARMV7, EVENT_21H) \
+ __PMC_EV(ARMV7, EVENT_22H) \
+ __PMC_EV(ARMV7, EVENT_23H) \
+ __PMC_EV(ARMV7, EVENT_24H) \
+ __PMC_EV(ARMV7, EVENT_25H) \
+ __PMC_EV(ARMV7, EVENT_26H) \
+ __PMC_EV(ARMV7, EVENT_27H) \
+ __PMC_EV(ARMV7, EVENT_28H) \
+ __PMC_EV(ARMV7, EVENT_29H) \
+ __PMC_EV(ARMV7, EVENT_2AH) \
+ __PMC_EV(ARMV7, EVENT_2BH) \
+ __PMC_EV(ARMV7, EVENT_2CH) \
+ __PMC_EV(ARMV7, EVENT_2DH) \
+ __PMC_EV(ARMV7, EVENT_2EH) \
+ __PMC_EV(ARMV7, EVENT_2FH) \
+ __PMC_EV(ARMV7, EVENT_30H) \
+ __PMC_EV(ARMV7, EVENT_31H) \
+ __PMC_EV(ARMV7, EVENT_32H) \
+ __PMC_EV(ARMV7, EVENT_33H) \
+ __PMC_EV(ARMV7, EVENT_34H) \
+ __PMC_EV(ARMV7, EVENT_35H) \
+ __PMC_EV(ARMV7, EVENT_36H) \
+ __PMC_EV(ARMV7, EVENT_37H) \
+ __PMC_EV(ARMV7, EVENT_38H) \
+ __PMC_EV(ARMV7, EVENT_39H) \
+ __PMC_EV(ARMV7, EVENT_3AH) \
+ __PMC_EV(ARMV7, EVENT_3BH) \
+ __PMC_EV(ARMV7, EVENT_3CH) \
+ __PMC_EV(ARMV7, EVENT_3DH) \
+ __PMC_EV(ARMV7, EVENT_3EH) \
+ __PMC_EV(ARMV7, EVENT_3FH) \
+ __PMC_EV(ARMV7, EVENT_40H) \
+ __PMC_EV(ARMV7, EVENT_41H) \
+ __PMC_EV(ARMV7, EVENT_42H) \
+ __PMC_EV(ARMV7, EVENT_43H) \
+ __PMC_EV(ARMV7, EVENT_44H) \
+ __PMC_EV(ARMV7, EVENT_45H) \
+ __PMC_EV(ARMV7, EVENT_46H) \
+ __PMC_EV(ARMV7, EVENT_47H) \
+ __PMC_EV(ARMV7, EVENT_48H) \
+ __PMC_EV(ARMV7, EVENT_49H) \
+ __PMC_EV(ARMV7, EVENT_4AH) \
+ __PMC_EV(ARMV7, EVENT_4BH) \
+ __PMC_EV(ARMV7, EVENT_4CH) \
+ __PMC_EV(ARMV7, EVENT_4DH) \
+ __PMC_EV(ARMV7, EVENT_4EH) \
+ __PMC_EV(ARMV7, EVENT_4FH) \
+ __PMC_EV(ARMV7, EVENT_50H) \
+ __PMC_EV(ARMV7, EVENT_51H) \
+ __PMC_EV(ARMV7, EVENT_52H) \
+ __PMC_EV(ARMV7, EVENT_53H) \
+ __PMC_EV(ARMV7, EVENT_54H) \
+ __PMC_EV(ARMV7, EVENT_55H) \
+ __PMC_EV(ARMV7, EVENT_56H) \
+ __PMC_EV(ARMV7, EVENT_57H) \
+ __PMC_EV(ARMV7, EVENT_58H) \
+ __PMC_EV(ARMV7, EVENT_59H) \
+ __PMC_EV(ARMV7, EVENT_5AH) \
+ __PMC_EV(ARMV7, EVENT_5BH) \
+ __PMC_EV(ARMV7, EVENT_5CH) \
+ __PMC_EV(ARMV7, EVENT_5DH) \
+ __PMC_EV(ARMV7, EVENT_5EH) \
+ __PMC_EV(ARMV7, EVENT_5FH) \
+ __PMC_EV(ARMV7, EVENT_60H) \
+ __PMC_EV(ARMV7, EVENT_61H) \
+ __PMC_EV(ARMV7, EVENT_62H) \
+ __PMC_EV(ARMV7, EVENT_63H) \
+ __PMC_EV(ARMV7, EVENT_64H) \
+ __PMC_EV(ARMV7, EVENT_65H) \
+ __PMC_EV(ARMV7, EVENT_66H) \
+ __PMC_EV(ARMV7, EVENT_67H) \
+ __PMC_EV(ARMV7, EVENT_68H) \
+ __PMC_EV(ARMV7, EVENT_69H) \
+ __PMC_EV(ARMV7, EVENT_6AH) \
+ __PMC_EV(ARMV7, EVENT_6BH) \
+ __PMC_EV(ARMV7, EVENT_6CH) \
+ __PMC_EV(ARMV7, EVENT_6DH) \
+ __PMC_EV(ARMV7, EVENT_6EH) \
+ __PMC_EV(ARMV7, EVENT_6FH) \
+ __PMC_EV(ARMV7, EVENT_70H) \
+ __PMC_EV(ARMV7, EVENT_71H) \
+ __PMC_EV(ARMV7, EVENT_72H) \
+ __PMC_EV(ARMV7, EVENT_73H) \
+ __PMC_EV(ARMV7, EVENT_74H) \
+ __PMC_EV(ARMV7, EVENT_75H) \
+ __PMC_EV(ARMV7, EVENT_76H) \
+ __PMC_EV(ARMV7, EVENT_77H) \
+ __PMC_EV(ARMV7, EVENT_78H) \
+ __PMC_EV(ARMV7, EVENT_79H) \
+ __PMC_EV(ARMV7, EVENT_7AH) \
+ __PMC_EV(ARMV7, EVENT_7BH) \
+ __PMC_EV(ARMV7, EVENT_7CH) \
+ __PMC_EV(ARMV7, EVENT_7DH) \
+ __PMC_EV(ARMV7, EVENT_7EH) \
+ __PMC_EV(ARMV7, EVENT_7FH) \
+ __PMC_EV(ARMV7, EVENT_80H) \
+ __PMC_EV(ARMV7, EVENT_81H) \
+ __PMC_EV(ARMV7, EVENT_82H) \
+ __PMC_EV(ARMV7, EVENT_83H) \
+ __PMC_EV(ARMV7, EVENT_84H) \
+ __PMC_EV(ARMV7, EVENT_85H) \
+ __PMC_EV(ARMV7, EVENT_86H) \
+ __PMC_EV(ARMV7, EVENT_87H) \
+ __PMC_EV(ARMV7, EVENT_88H) \
+ __PMC_EV(ARMV7, EVENT_89H) \
+ __PMC_EV(ARMV7, EVENT_8AH) \
+ __PMC_EV(ARMV7, EVENT_8BH) \
+ __PMC_EV(ARMV7, EVENT_8CH) \
+ __PMC_EV(ARMV7, EVENT_8DH) \
+ __PMC_EV(ARMV7, EVENT_8EH) \
+ __PMC_EV(ARMV7, EVENT_8FH) \
+ __PMC_EV(ARMV7, EVENT_90H) \
+ __PMC_EV(ARMV7, EVENT_91H) \
+ __PMC_EV(ARMV7, EVENT_92H) \
+ __PMC_EV(ARMV7, EVENT_93H) \
+ __PMC_EV(ARMV7, EVENT_94H) \
+ __PMC_EV(ARMV7, EVENT_95H) \
+ __PMC_EV(ARMV7, EVENT_96H) \
+ __PMC_EV(ARMV7, EVENT_97H) \
+ __PMC_EV(ARMV7, EVENT_98H) \
+ __PMC_EV(ARMV7, EVENT_99H) \
+ __PMC_EV(ARMV7, EVENT_9AH) \
+ __PMC_EV(ARMV7, EVENT_9BH) \
+ __PMC_EV(ARMV7, EVENT_9CH) \
+ __PMC_EV(ARMV7, EVENT_9DH) \
+ __PMC_EV(ARMV7, EVENT_9EH) \
+ __PMC_EV(ARMV7, EVENT_9FH) \
+ __PMC_EV(ARMV7, EVENT_A0H) \
+ __PMC_EV(ARMV7, EVENT_A1H) \
+ __PMC_EV(ARMV7, EVENT_A2H) \
+ __PMC_EV(ARMV7, EVENT_A3H) \
+ __PMC_EV(ARMV7, EVENT_A4H) \
+ __PMC_EV(ARMV7, EVENT_A5H) \
+ __PMC_EV(ARMV7, EVENT_A6H) \
+ __PMC_EV(ARMV7, EVENT_A7H) \
+ __PMC_EV(ARMV7, EVENT_A8H) \
+ __PMC_EV(ARMV7, EVENT_A9H) \
+ __PMC_EV(ARMV7, EVENT_AAH) \
+ __PMC_EV(ARMV7, EVENT_ABH) \
+ __PMC_EV(ARMV7, EVENT_ACH) \
+ __PMC_EV(ARMV7, EVENT_ADH) \
+ __PMC_EV(ARMV7, EVENT_AEH) \
+ __PMC_EV(ARMV7, EVENT_AFH) \
+ __PMC_EV(ARMV7, EVENT_B0H) \
+ __PMC_EV(ARMV7, EVENT_B1H) \
+ __PMC_EV(ARMV7, EVENT_B2H) \
+ __PMC_EV(ARMV7, EVENT_B3H) \
+ __PMC_EV(ARMV7, EVENT_B4H) \
+ __PMC_EV(ARMV7, EVENT_B5H) \
+ __PMC_EV(ARMV7, EVENT_B6H) \
+ __PMC_EV(ARMV7, EVENT_B7H) \
+ __PMC_EV(ARMV7, EVENT_B8H) \
+ __PMC_EV(ARMV7, EVENT_B9H) \
+ __PMC_EV(ARMV7, EVENT_BAH) \
+ __PMC_EV(ARMV7, EVENT_BBH) \
+ __PMC_EV(ARMV7, EVENT_BCH) \
+ __PMC_EV(ARMV7, EVENT_BDH) \
+ __PMC_EV(ARMV7, EVENT_BEH) \
+ __PMC_EV(ARMV7, EVENT_BFH) \
+ __PMC_EV(ARMV7, EVENT_C0H) \
+ __PMC_EV(ARMV7, EVENT_C1H) \
+ __PMC_EV(ARMV7, EVENT_C2H) \
+ __PMC_EV(ARMV7, EVENT_C3H) \
+ __PMC_EV(ARMV7, EVENT_C4H) \
+ __PMC_EV(ARMV7, EVENT_C5H) \
+ __PMC_EV(ARMV7, EVENT_C6H) \
+ __PMC_EV(ARMV7, EVENT_C7H) \
+ __PMC_EV(ARMV7, EVENT_C8H) \
+ __PMC_EV(ARMV7, EVENT_C9H) \
+ __PMC_EV(ARMV7, EVENT_CAH) \
+ __PMC_EV(ARMV7, EVENT_CBH) \
+ __PMC_EV(ARMV7, EVENT_CCH) \
+ __PMC_EV(ARMV7, EVENT_CDH) \
+ __PMC_EV(ARMV7, EVENT_CEH) \
+ __PMC_EV(ARMV7, EVENT_CFH) \
+ __PMC_EV(ARMV7, EVENT_D0H) \
+ __PMC_EV(ARMV7, EVENT_D1H) \
+ __PMC_EV(ARMV7, EVENT_D2H) \
+ __PMC_EV(ARMV7, EVENT_D3H) \
+ __PMC_EV(ARMV7, EVENT_D4H) \
+ __PMC_EV(ARMV7, EVENT_D5H) \
+ __PMC_EV(ARMV7, EVENT_D6H) \
+ __PMC_EV(ARMV7, EVENT_D7H) \
+ __PMC_EV(ARMV7, EVENT_D8H) \
+ __PMC_EV(ARMV7, EVENT_D9H) \
+ __PMC_EV(ARMV7, EVENT_DAH) \
+ __PMC_EV(ARMV7, EVENT_DBH) \
+ __PMC_EV(ARMV7, EVENT_DCH) \
+ __PMC_EV(ARMV7, EVENT_DDH) \
+ __PMC_EV(ARMV7, EVENT_DEH) \
+ __PMC_EV(ARMV7, EVENT_DFH) \
+ __PMC_EV(ARMV7, EVENT_E0H) \
+ __PMC_EV(ARMV7, EVENT_E1H) \
+ __PMC_EV(ARMV7, EVENT_E2H) \
+ __PMC_EV(ARMV7, EVENT_E3H) \
+ __PMC_EV(ARMV7, EVENT_E4H) \
+ __PMC_EV(ARMV7, EVENT_E5H) \
+ __PMC_EV(ARMV7, EVENT_E6H) \
+ __PMC_EV(ARMV7, EVENT_E7H) \
+ __PMC_EV(ARMV7, EVENT_E8H) \
+ __PMC_EV(ARMV7, EVENT_E9H) \
+ __PMC_EV(ARMV7, EVENT_EAH) \
+ __PMC_EV(ARMV7, EVENT_EBH) \
+ __PMC_EV(ARMV7, EVENT_ECH) \
+ __PMC_EV(ARMV7, EVENT_EDH) \
+ __PMC_EV(ARMV7, EVENT_EEH) \
+ __PMC_EV(ARMV7, EVENT_EFH) \
+ __PMC_EV(ARMV7, EVENT_F0H) \
+ __PMC_EV(ARMV7, EVENT_F1H) \
+ __PMC_EV(ARMV7, EVENT_F2H) \
+ __PMC_EV(ARMV7, EVENT_F3H) \
+ __PMC_EV(ARMV7, EVENT_F4H) \
+ __PMC_EV(ARMV7, EVENT_F5H) \
+ __PMC_EV(ARMV7, EVENT_F6H) \
+ __PMC_EV(ARMV7, EVENT_F7H) \
+ __PMC_EV(ARMV7, EVENT_F8H) \
+ __PMC_EV(ARMV7, EVENT_F9H) \
+ __PMC_EV(ARMV7, EVENT_FAH) \
+ __PMC_EV(ARMV7, EVENT_FBH) \
+ __PMC_EV(ARMV7, EVENT_FCH) \
+ __PMC_EV(ARMV7, EVENT_FDH) \
+ __PMC_EV(ARMV7, EVENT_FEH) \
+ __PMC_EV(ARMV7, EVENT_FFH)
-#define PMC_EV_ARMV7_FIRST PMC_EV_ARMV7_PMNC_SW_INCR
-#define PMC_EV_ARMV7_LAST PMC_EV_ARMV7_CPU_CYCLES
+#define PMC_EV_ARMV7_FIRST PMC_EV_ARMV7_EVENT_00H
+#define PMC_EV_ARMV7_LAST PMC_EV_ARMV7_EVENT_FFH
+
+#define __PMC_EV_ALIAS_ARMV7_COMMON() \
+ __PMC_EV_ALIAS("PMNC_SW_INCR", ARMV7_EVENT_00H) \
+ __PMC_EV_ALIAS("L1_ICACHE_REFILL", ARMV7_EVENT_01H) \
+ __PMC_EV_ALIAS("ITLB_REFILL", ARMV7_EVENT_02H) \
+ __PMC_EV_ALIAS("L1_DCACHE_REFILL", ARMV7_EVENT_03H) \
+ __PMC_EV_ALIAS("L1_DCACHE_ACCESS", ARMV7_EVENT_04H) \
+ __PMC_EV_ALIAS("DTLB_REFILL", ARMV7_EVENT_05H) \
+ __PMC_EV_ALIAS("MEM_READ", ARMV7_EVENT_06H) \
+ __PMC_EV_ALIAS("MEM_WRITE", ARMV7_EVENT_07H) \
+ __PMC_EV_ALIAS("INSTR_EXECUTED", ARMV7_EVENT_08H) \
+ __PMC_EV_ALIAS("EXC_TAKEN", ARMV7_EVENT_09H) \
+ __PMC_EV_ALIAS("EXC_EXECUTED", ARMV7_EVENT_0AH) \
+ __PMC_EV_ALIAS("CID_WRITE", ARMV7_EVENT_0BH) \
+ __PMC_EV_ALIAS("PC_WRITE", ARMV7_EVENT_0CH) \
+ __PMC_EV_ALIAS("PC_IMM_BRANCH", ARMV7_EVENT_0DH) \
+ __PMC_EV_ALIAS("PC_PROC_RETURN", ARMV7_EVENT_0EH) \
+ __PMC_EV_ALIAS("MEM_UNALIGNED_ACCESS", ARMV7_EVENT_0FH) \
+ __PMC_EV_ALIAS("PC_BRANCH_MIS_PRED", ARMV7_EVENT_10H) \
+ __PMC_EV_ALIAS("CLOCK_CYCLES", ARMV7_EVENT_11H) \
+ __PMC_EV_ALIAS("PC_BRANCH_PRED", ARMV7_EVENT_12H) \
+ __PMC_EV_ALIAS("MEM_ACCESS", ARMV7_EVENT_13H) \
+ __PMC_EV_ALIAS("L1_ICACHE_ACCESS", ARMV7_EVENT_14H) \
+ __PMC_EV_ALIAS("L1_DCACHE_WB", ARMV7_EVENT_15H) \
+ __PMC_EV_ALIAS("L2_CACHE_ACCESS", ARMV7_EVENT_16H) \
+ __PMC_EV_ALIAS("L2_CACHE_REFILL", ARMV7_EVENT_17H) \
+ __PMC_EV_ALIAS("L2_CACHE_WB", ARMV7_EVENT_18H) \
+ __PMC_EV_ALIAS("BUS_ACCESS", ARMV7_EVENT_19H) \
+ __PMC_EV_ALIAS("MEM_ERROR", ARMV7_EVENT_1AH) \
+ __PMC_EV_ALIAS("INSTR_SPEC", ARMV7_EVENT_1BH) \
+ __PMC_EV_ALIAS("TTBR_WRITE", ARMV7_EVENT_1CH) \
+ __PMC_EV_ALIAS("BUS_CYCLES", ARMV7_EVENT_1DH) \
+ __PMC_EV_ALIAS("CPU_CYCLES", ARMV7_EVENT_FFH)
+
+#define __PMC_EV_ALIAS_ARMV7_CORTEX_A8() \
+ __PMC_EV_ALIAS_ARMV7_COMMON()
+
+#define __PMC_EV_ALIAS_ARMV7_CORTEX_A9() \
+ __PMC_EV_ALIAS_ARMV7_COMMON() \
+ __PMC_EV_ALIAS("JAVA_BYTECODE", ARMV7_EVENT_40H) \
+ __PMC_EV_ALIAS("SOFTWARE_JAVA_BYTECODE", ARMV7_EVENT_41H) \
+ __PMC_EV_ALIAS("JAZELLE_BACKWARD_BRANCH", ARMV7_EVENT_42H) \
+ __PMC_EV_ALIAS("COHERENT_LINEFILL_MISSC", ARMV7_EVENT_50H) \
+ __PMC_EV_ALIAS("COHERENT_LINEFILL_HITC", ARMV7_EVENT_51H) \
+ __PMC_EV_ALIAS("INSTR_CACHE_DEPENDENT_STALL", ARMV7_EVENT_60H) \
+ __PMC_EV_ALIAS("DATA_CACHE_DEPENDENT_STALL", ARMV7_EVENT_61H) \
+ __PMC_EV_ALIAS("MAIN_TLB_MISS_STALL", ARMV7_EVENT_62H) \
+ __PMC_EV_ALIAS("STREX_PASSED", ARMV7_EVENT_63H) \
+ __PMC_EV_ALIAS("STREX_FAILED", ARMV7_EVENT_64H) \
+ __PMC_EV_ALIAS("DATA_EVICTION", ARMV7_EVENT_65H) \
+ __PMC_EV_ALIAS("ISSUE_DNOT_DISPATCH_ANY_INSTR", ARMV7_EVENT_66H) \
+ __PMC_EV_ALIAS("ISSUE_IS_EMPTY", ARMV7_EVENT_67H) \
+ __PMC_EV_ALIAS("MAIN_EXECUTION_UNIT_PIPE", ARMV7_EVENT_70H) \
+ __PMC_EV_ALIAS("SECOND_EXECUTION_UNIT_PIPE", ARMV7_EVENT_71H) \
+ __PMC_EV_ALIAS("LOAD_STORE_PIPE", ARMV7_EVENT_72H) \
+ __PMC_EV_ALIAS("FLOATING_POINT_INSTR_RENAMED", ARMV7_EVENT_73H) \
+ __PMC_EV_ALIAS("NEON_INSTRS_RENAMED", ARMV7_EVENT_74H) \
+ __PMC_EV_ALIAS("PLD_STALL", ARMV7_EVENT_80H) \
+ __PMC_EV_ALIAS("WRITE_STALL", ARMV7_EVENT_81H) \
+ __PMC_EV_ALIAS("INSTR_MAIN_TLB_MISS_STALL", ARMV7_EVENT_82H) \
+ __PMC_EV_ALIAS("DATA_MAIN_TLB_MISS_STALL", ARMV7_EVENT_83H) \
+ __PMC_EV_ALIAS("INSTR_MICRO_TLB_MISS_STALL", ARMV7_EVENT_84H) \
+ __PMC_EV_ALIAS("DATA_MICRO_TLB_MISS_STALL", ARMV7_EVENT_85H) \
+ __PMC_EV_ALIAS("DMB_STALL", ARMV7_EVENT_86H) \
+ __PMC_EV_ALIAS("INTEGER_CORE_CLOCK_ENABLED", ARMV7_EVENT_8AH) \
+ __PMC_EV_ALIAS("DATA_ENGINE_CLOCK_ENABLED", ARMV7_EVENT_8BH) \
+ __PMC_EV_ALIAS("ISB", ARMV7_EVENT_90H) \
+ __PMC_EV_ALIAS("DSB", ARMV7_EVENT_91H) \
+ __PMC_EV_ALIAS("DMB", ARMV7_EVENT_92H) \
+ __PMC_EV_ALIAS("EXTERNAL_INTERRUPT", ARMV7_EVENT_93H) \
+ __PMC_EV_ALIAS("PLE_CACHE_LINE_REQ_COMPLETED", ARMV7_EVENT_A0H) \
+ __PMC_EV_ALIAS("PLE_CACHE_LINE_REQ_SKIPPED", ARMV7_EVENT_A1H) \
+ __PMC_EV_ALIAS("PLE_FIFO_FLUSH", ARMV7_EVENT_A2H) \
+ __PMC_EV_ALIAS("PLE_REQUEST_COMPLETED", ARMV7_EVENT_A3H) \
+ __PMC_EV_ALIAS("PLE_FIFO_OVERFLOW", ARMV7_EVENT_A4H) \
+ __PMC_EV_ALIAS("PLE_REQUEST_PROGRAMMED", ARMV7_EVENT_A5H)
/*
* ARMv8 Events
diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c
new file mode 100644
index 000000000000..e9081e3ed9b0
--- /dev/null
+++ b/sys/dev/ichiic/ig4_iic.c
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 2014 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com> and was subsequently ported
+ * to FreeBSD by Michael Gmelin <freebsd@grem.de>
+ *
+ * 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 DragonFly Project 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 HOLDERS 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Intel fourth generation mobile cpus integrated I2C device, smbus driver.
+ *
+ * See ig4_reg.h for datasheet reference and notes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/errno.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/syslog.h>
+#include <sys/bus.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/smbus/smbconf.h>
+
+#include <dev/ichiic/ig4_reg.h>
+#include <dev/ichiic/ig4_var.h>
+
+#define TRANS_NORMAL 1
+#define TRANS_PCALL 2
+#define TRANS_BLOCK 3
+
+static void ig4iic_start(void *xdev);
+static void ig4iic_intr(void *cookie);
+static void ig4iic_dump(ig4iic_softc_t *sc);
+
+static int ig4_dump;
+SYSCTL_INT(_debug, OID_AUTO, ig4_dump, CTLTYPE_INT | CTLFLAG_RW,
+ &ig4_dump, 0, "");
+
+/*
+ * Low-level inline support functions
+ */
+static __inline void
+reg_write(ig4iic_softc_t *sc, uint32_t reg, uint32_t value)
+{
+ bus_write_4(sc->regs_res, reg, value);
+ bus_barrier(sc->regs_res, reg, 4, BUS_SPACE_BARRIER_WRITE);
+}
+
+static __inline uint32_t
+reg_read(ig4iic_softc_t *sc, uint32_t reg)
+{
+ uint32_t value;
+
+ bus_barrier(sc->regs_res, reg, 4, BUS_SPACE_BARRIER_READ);
+ value = bus_read_4(sc->regs_res, reg);
+ return (value);
+}
+
+/*
+ * Enable or disable the controller and wait for the controller to acknowledge
+ * the state change.
+ */
+static int
+set_controller(ig4iic_softc_t *sc, uint32_t ctl)
+{
+ int retry;
+ int error;
+ uint32_t v;
+
+ reg_write(sc, IG4_REG_I2C_EN, ctl);
+ error = SMB_ETIMEOUT;
+
+ for (retry = 100; retry > 0; --retry) {
+ v = reg_read(sc, IG4_REG_ENABLE_STATUS);
+ if (((v ^ ctl) & IG4_I2C_ENABLE) == 0) {
+ error = 0;
+ break;
+ }
+ mtx_sleep(sc, &sc->mutex, 0, "i2cslv", 1);
+ }
+ return (error);
+}
+
+/*
+ * Wait up to 25ms for the requested status using a 25uS polling loop.
+ */
+static int
+wait_status(ig4iic_softc_t *sc, uint32_t status)
+{
+ uint32_t v;
+ int error;
+ int txlvl = -1;
+ u_int count_us = 0;
+ u_int limit_us = 25000; /* 25ms */
+
+ error = SMB_ETIMEOUT;
+
+ for (;;) {
+ /*
+ * Check requested status
+ */
+ v = reg_read(sc, IG4_REG_I2C_STA);
+ if (v & status) {
+ error = 0;
+ break;
+ }
+
+ /*
+ * When waiting for receive data break-out if the interrupt
+ * loaded data into the FIFO.
+ */
+ if (status & IG4_STATUS_RX_NOTEMPTY) {
+ if (sc->rpos != sc->rnext) {
+ error = 0;
+ break;
+ }
+ }
+
+ /*
+ * When waiting for the transmit FIFO to become empty,
+ * reset the timeout if we see a change in the transmit
+ * FIFO level as progress is being made.
+ */
+ if (status & IG4_STATUS_TX_EMPTY) {
+ v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK;
+ if (txlvl != v) {
+ txlvl = v;
+ count_us = 0;
+ }
+ }
+
+ /*
+ * Stop if we've run out of time.
+ */
+ if (count_us >= limit_us)
+ break;
+
+ /*
+ * When waiting for receive data let the interrupt do its
+ * work, otherwise poll with the lock held.
+ */
+ if (status & IG4_STATUS_RX_NOTEMPTY) {
+ mtx_sleep(sc, &sc->mutex, PZERO, "i2cwait",
+ (hz + 99) / 100); /* sleep up to 10ms */
+ count_us += 10000;
+ } else {
+ DELAY(25);
+ count_us += 25;
+ }
+ }
+
+ return (error);
+}
+
+/*
+ * Read I2C data. The data might have already been read by
+ * the interrupt code, otherwise it is sitting in the data
+ * register.
+ */
+static uint8_t
+data_read(ig4iic_softc_t *sc)
+{
+ uint8_t c;
+
+ if (sc->rpos == sc->rnext) {
+ c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
+ } else {
+ c = sc->rbuf[sc->rpos & IG4_RBUFMASK];
+ ++sc->rpos;
+ }
+ return (c);
+}
+
+/*
+ * Set the slave address. The controller must be disabled when
+ * changing the address.
+ *
+ * This operation does not issue anything to the I2C bus but sets
+ * the target address for when the controller later issues a START.
+ */
+static void
+set_slave_addr(ig4iic_softc_t *sc, uint8_t slave, int trans_op)
+{
+ uint32_t tar;
+ uint32_t ctl;
+ int use_10bit;
+
+ use_10bit = sc->use_10bit;
+ if (trans_op & SMB_TRANS_7BIT)
+ use_10bit = 0;
+ if (trans_op & SMB_TRANS_10BIT)
+ use_10bit = 1;
+
+ if (sc->slave_valid && sc->last_slave == slave &&
+ sc->use_10bit == use_10bit) {
+ return;
+ }
+ sc->use_10bit = use_10bit;
+
+ /*
+ * Wait for TXFIFO to drain before disabling the controller.
+ *
+ * If a write message has not been completed it's really a
+ * programming error, but for now in that case issue an extra
+ * byte + STOP.
+ *
+ * If a read message has not been completed it's also a programming
+ * error, for now just ignore it.
+ */
+ wait_status(sc, IG4_STATUS_TX_NOTFULL);
+ if (sc->write_started) {
+ reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_STOP);
+ sc->write_started = 0;
+ }
+ if (sc->read_started)
+ sc->read_started = 0;
+ wait_status(sc, IG4_STATUS_TX_EMPTY);
+
+ set_controller(sc, 0);
+ ctl = reg_read(sc, IG4_REG_CTL);
+ ctl &= ~IG4_CTL_10BIT;
+ ctl |= IG4_CTL_RESTARTEN;
+
+ tar = slave;
+ if (sc->use_10bit) {
+ tar |= IG4_TAR_10BIT;
+ ctl |= IG4_CTL_10BIT;
+ }
+ reg_write(sc, IG4_REG_CTL, ctl);
+ reg_write(sc, IG4_REG_TAR_ADD, tar);
+ set_controller(sc, IG4_I2C_ENABLE);
+ sc->slave_valid = 1;
+ sc->last_slave = slave;
+}
+
+/*
+ * Issue START with byte command, possible count, and a variable length
+ * read or write buffer, then possible turn-around read. The read also
+ * has a possible count received.
+ *
+ * For SMBUS -
+ *
+ * Quick: START+ADDR+RD/WR STOP
+ *
+ * Normal: START+ADDR+WR CMD DATA..DATA STOP
+ *
+ * START+ADDR+RD CMD
+ * RESTART+ADDR RDATA..RDATA STOP
+ * (can also be used for I2C transactions)
+ *
+ * Process Call: START+ADDR+WR CMD DATAL DATAH
+ * RESTART+ADDR+RD RDATAL RDATAH STOP
+ *
+ * Block: START+ADDR+RD CMD
+ * RESTART+ADDR+RD RCOUNT DATA... STOP
+ *
+ * START+ADDR+WR CMD
+ * RESTART+ADDR+WR WCOUNT DATA... STOP
+ *
+ * For I2C - basically, no *COUNT fields, possibly no *CMD field. If the
+ * sender needs to issue a 2-byte command it will incorporate it
+ * into the write buffer and also set NOCMD.
+ *
+ * Generally speaking, the START+ADDR / RESTART+ADDR is handled automatically
+ * by the controller at the beginning of a command sequence or on a data
+ * direction turn-around, and we only need to tell it when to issue the STOP.
+ */
+static int
+smb_transaction(ig4iic_softc_t *sc, char cmd, int op,
+ char *wbuf, int wcount, char *rbuf, int rcount, int *actualp)
+{
+ int error;
+ int unit;
+ uint32_t last;
+
+ /*
+ * Debugging - dump registers
+ */
+ if (ig4_dump) {
+ unit = device_get_unit(sc->dev);
+ if (ig4_dump & (1 << unit)) {
+ ig4_dump &= ~(1 << unit);
+ ig4iic_dump(sc);
+ }
+ }
+
+ /*
+ * Issue START or RESTART with next data byte, clear any previous
+ * abort condition that may have been holding the txfifo in reset.
+ */
+ last = IG4_DATA_RESTART;
+ reg_read(sc, IG4_REG_CLR_TX_ABORT);
+ if (actualp)
+ *actualp = 0;
+
+ /*
+ * Issue command if not told otherwise (smbus).
+ */
+ if ((op & SMB_TRANS_NOCMD) == 0) {
+ error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
+ if (error)
+ goto done;
+ last |= (u_char)cmd;
+ if (wcount == 0 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0)
+ last |= IG4_DATA_STOP;
+ reg_write(sc, IG4_REG_DATA_CMD, last);
+ last = 0;
+ }
+
+ /*
+ * Clean out any previously received data.
+ */
+ if (sc->rpos != sc->rnext &&
+ (op & SMB_TRANS_NOREPORT) == 0) {
+ device_printf(sc->dev,
+ "discarding %d bytes of spurious data\n",
+ sc->rnext - sc->rpos);
+ }
+ sc->rpos = 0;
+ sc->rnext = 0;
+
+ /*
+ * If writing and not told otherwise, issue the write count (smbus).
+ */
+ if (wcount && (op & SMB_TRANS_NOCNT) == 0) {
+ error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
+ if (error)
+ goto done;
+ last |= (u_char)cmd;
+ reg_write(sc, IG4_REG_DATA_CMD, last);
+ last = 0;
+ }
+
+ /*
+ * Bulk write (i2c)
+ */
+ while (wcount) {
+ error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
+ if (error)
+ goto done;
+ last |= (u_char)*wbuf;
+ if (wcount == 1 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0)
+ last |= IG4_DATA_STOP;
+ reg_write(sc, IG4_REG_DATA_CMD, last);
+ --wcount;
+ ++wbuf;
+ last = 0;
+ }
+
+ /*
+ * Issue reads to xmit FIFO (strange, I know) to tell the controller
+ * to clock in data. At the moment just issue one read ahead to
+ * pipeline the incoming data.
+ *
+ * NOTE: In the case of NOCMD and wcount == 0 we still issue a
+ * RESTART here, even if the data direction has not changed
+ * from the previous CHAINing call. This we force the RESTART.
+ * (A new START is issued automatically by the controller in
+ * the other nominal cases such as a data direction change or
+ * a previous STOP was issued).
+ *
+ * If this will be the last byte read we must also issue the STOP
+ * at the end of the read.
+ */
+ if (rcount) {
+ last = IG4_DATA_RESTART | IG4_DATA_COMMAND_RD;
+ if (rcount == 1 &&
+ (op & (SMB_TRANS_NOSTOP | SMB_TRANS_NOCNT)) ==
+ SMB_TRANS_NOCNT) {
+ last |= IG4_DATA_STOP;
+ }
+ reg_write(sc, IG4_REG_DATA_CMD, last);
+ last = IG4_DATA_COMMAND_RD;
+ }
+
+ /*
+ * Bulk read (i2c) and count field handling (smbus)
+ */
+ while (rcount) {
+ /*
+ * Maintain a pipeline by queueing the allowance for the next
+ * read before waiting for the current read.
+ */
+ if (rcount > 1) {
+ if (op & SMB_TRANS_NOCNT)
+ last = (rcount == 2) ? IG4_DATA_STOP : 0;
+ else
+ last = 0;
+ reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD |
+ last);
+ }
+ error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
+ if (error) {
+ if ((op & SMB_TRANS_NOREPORT) == 0) {
+ device_printf(sc->dev,
+ "rx timeout addr 0x%02x\n",
+ sc->last_slave);
+ }
+ goto done;
+ }
+ last = data_read(sc);
+
+ if (op & SMB_TRANS_NOCNT) {
+ *rbuf = (u_char)last;
+ ++rbuf;
+ --rcount;
+ if (actualp)
+ ++*actualp;
+ } else {
+ /*
+ * Handle count field (smbus), which is not part of
+ * the rcount'ed buffer. The first read data in a
+ * bulk transfer is the count.
+ *
+ * XXX if rcount is loaded as 0 how do I generate a
+ * STOP now without issuing another RD or WR?
+ */
+ if (rcount > (u_char)last)
+ rcount = (u_char)last;
+ op |= SMB_TRANS_NOCNT;
+ }
+ }
+ error = 0;
+done:
+ /* XXX wait for xmit buffer to become empty */
+ last = reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
+
+ return (error);
+}
+
+/*
+ * SMBUS API FUNCTIONS
+ *
+ * Called from ig4iic_pci_attach/detach()
+ */
+int
+ig4iic_attach(ig4iic_softc_t *sc)
+{
+ int error;
+ uint32_t v;
+
+ v = reg_read(sc, IG4_REG_COMP_TYPE);
+ v = reg_read(sc, IG4_REG_COMP_PARAM1);
+ v = reg_read(sc, IG4_REG_GENERAL);
+ if ((v & IG4_GENERAL_SWMODE) == 0) {
+ v |= IG4_GENERAL_SWMODE;
+ reg_write(sc, IG4_REG_GENERAL, v);
+ v = reg_read(sc, IG4_REG_GENERAL);
+ }
+
+ v = reg_read(sc, IG4_REG_SW_LTR_VALUE);
+ v = reg_read(sc, IG4_REG_AUTO_LTR_VALUE);
+
+ v = reg_read(sc, IG4_REG_COMP_VER);
+ if (v != IG4_COMP_VER) {
+ error = ENXIO;
+ goto done;
+ }
+ v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
+ v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
+ v = reg_read(sc, IG4_REG_FS_SCL_HCNT);
+ v = reg_read(sc, IG4_REG_FS_SCL_LCNT);
+ v = reg_read(sc, IG4_REG_SDA_HOLD);
+
+ v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
+ reg_write(sc, IG4_REG_FS_SCL_HCNT, v);
+ v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
+ reg_write(sc, IG4_REG_FS_SCL_LCNT, v);
+
+ /*
+ * Program based on a 25000 Hz clock. This is a bit of a
+ * hack (obviously). The defaults are 400 and 470 for standard
+ * and 60 and 130 for fast. The defaults for standard fail
+ * utterly (presumably cause an abort) because the clock time
+ * is ~18.8ms by default. This brings it down to ~4ms (for now).
+ */
+ reg_write(sc, IG4_REG_SS_SCL_HCNT, 100);
+ reg_write(sc, IG4_REG_SS_SCL_LCNT, 125);
+ reg_write(sc, IG4_REG_FS_SCL_HCNT, 100);
+ reg_write(sc, IG4_REG_FS_SCL_LCNT, 125);
+
+ /*
+ * Use a threshold of 1 so we get interrupted on each character,
+ * allowing us to use mtx_sleep() in our poll code. Not perfect
+ * but this is better than using DELAY() for receiving data.
+ */
+ reg_write(sc, IG4_REG_RX_TL, 1);
+
+ reg_write(sc, IG4_REG_CTL,
+ IG4_CTL_MASTER |
+ IG4_CTL_SLAVE_DISABLE |
+ IG4_CTL_RESTARTEN |
+ IG4_CTL_SPEED_STD);
+
+ sc->smb = device_add_child(sc->dev, "smbus", -1);
+ if (sc->smb == NULL) {
+ device_printf(sc->dev, "smbus driver not found\n");
+ error = ENXIO;
+ goto done;
+ }
+
+#if 0
+ /*
+ * Don't do this, it blows up the PCI config
+ */
+ reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT);
+ reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT);
+#endif
+
+ /*
+ * Interrupt on STOP detect or receive character ready
+ */
+ reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET |
+ IG4_INTR_RX_FULL);
+ mtx_lock(&sc->mutex);
+ if (set_controller(sc, 0))
+ device_printf(sc->dev, "controller error during attach-1\n");
+ if (set_controller(sc, IG4_I2C_ENABLE))
+ device_printf(sc->dev, "controller error during attach-2\n");
+ mtx_unlock(&sc->mutex);
+ error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE,
+ NULL, ig4iic_intr, sc, &sc->intr_handle);
+ if (error) {
+ device_printf(sc->dev,
+ "Unable to setup irq: error %d\n", error);
+ }
+
+ sc->enum_hook.ich_func = ig4iic_start;
+ sc->enum_hook.ich_arg = sc->dev;
+
+ /* We have to wait until interrupts are enabled. I2C read and write
+ * only works if the interrupts are available.
+ */
+ if (config_intrhook_establish(&sc->enum_hook) != 0)
+ error = ENOMEM;
+ else
+ error = 0;
+
+done:
+ return (error);
+}
+
+void
+ig4iic_start(void *xdev)
+{
+ int error;
+ ig4iic_softc_t *sc;
+ device_t dev = (device_t)xdev;
+
+ sc = device_get_softc(dev);
+
+ config_intrhook_disestablish(&sc->enum_hook);
+
+ /* Attach us to the smbus */
+ error = bus_generic_attach(sc->dev);
+ if (error) {
+ device_printf(sc->dev,
+ "failed to attach child: error %d\n", error);
+ }
+}
+
+
+
+int
+ig4iic_detach(ig4iic_softc_t *sc)
+{
+ int error;
+
+ if (device_is_attached(sc->dev)) {
+ error = bus_generic_detach(sc->dev);
+ if (error)
+ return (error);
+ }
+ if (sc->smb)
+ device_delete_child(sc->dev, sc->smb);
+ if (sc->intr_handle)
+ bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
+
+ mtx_lock(&sc->mutex);
+
+ sc->smb = NULL;
+ sc->intr_handle = NULL;
+ reg_write(sc, IG4_REG_INTR_MASK, 0);
+ reg_read(sc, IG4_REG_CLR_INTR);
+ set_controller(sc, 0);
+
+ mtx_unlock(&sc->mutex);
+ return (0);
+}
+
+int
+ig4iic_smb_callback(device_t dev, int index, void *data)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ switch (index) {
+ case SMB_REQUEST_BUS:
+ error = 0;
+ break;
+ case SMB_RELEASE_BUS:
+ error = 0;
+ break;
+ default:
+ error = SMB_EABORT;
+ break;
+ }
+
+ mtx_unlock(&sc->mutex);
+
+ return (error);
+}
+
+/*
+ * Quick command. i.e. START + cmd + R/W + STOP and no data. It is
+ * unclear to me how I could implement this with the intel i2c controller
+ * because the controler sends STARTs and STOPs automatically with data.
+ */
+int
+ig4iic_smb_quick(device_t dev, u_char slave, int how)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ switch (how) {
+ case SMB_QREAD:
+ error = SMB_ENOTSUPP;
+ break;
+ case SMB_QWRITE:
+ error = SMB_ENOTSUPP;
+ break;
+ default:
+ error = SMB_ENOTSUPP;
+ break;
+ }
+ mtx_unlock(&sc->mutex);
+
+ return (error);
+}
+
+/*
+ * Incremental send byte without stop (?). It is unclear why the slave
+ * address is specified if this presumably is used in combination with
+ * ig4iic_smb_quick().
+ *
+ * (Also, how would this work anyway? Issue the last byte with writeb()?)
+ */
+int
+ig4iic_smb_sendb(device_t dev, u_char slave, char byte)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ uint32_t cmd;
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ cmd = byte;
+ if (wait_status(sc, IG4_STATUS_TX_NOTFULL) == 0) {
+ reg_write(sc, IG4_REG_DATA_CMD, cmd);
+ error = 0;
+ } else {
+ error = SMB_ETIMEOUT;
+ }
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+/*
+ * Incremental receive byte without stop (?). It is unclear why the slave
+ * address is specified if this presumably is used in combination with
+ * ig4iic_smb_quick().
+ */
+int
+ig4iic_smb_recvb(device_t dev, u_char slave, char *byte)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD);
+ if (wait_status(sc, IG4_STATUS_RX_NOTEMPTY) == 0) {
+ *byte = data_read(sc);
+ error = 0;
+ } else {
+ *byte = 0;
+ error = SMB_ETIMEOUT;
+ }
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+/*
+ * Write command and single byte in transaction.
+ */
+int
+ig4iic_smb_writeb(device_t dev, u_char slave, char cmd, char byte)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
+ &byte, 1, NULL, 0, NULL);
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+/*
+ * Write command and single word in transaction.
+ */
+int
+ig4iic_smb_writew(device_t dev, u_char slave, char cmd, short word)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ char buf[2];
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ buf[0] = word & 0xFF;
+ buf[1] = word >> 8;
+ error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
+ buf, 2, NULL, 0, NULL);
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+/*
+ * write command and read single byte in transaction.
+ */
+int
+ig4iic_smb_readb(device_t dev, u_char slave, char cmd, char *byte)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
+ NULL, 0, byte, 1, NULL);
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+/*
+ * write command and read word in transaction.
+ */
+int
+ig4iic_smb_readw(device_t dev, u_char slave, char cmd, short *word)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ char buf[2];
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
+ NULL, 0, buf, 2, NULL)) == 0) {
+ *word = (u_char)buf[0] | ((u_char)buf[1] << 8);
+ }
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+/*
+ * write command and word and read word in transaction
+ */
+int
+ig4iic_smb_pcall(device_t dev, u_char slave, char cmd,
+ short sdata, short *rdata)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ char rbuf[2];
+ char wbuf[2];
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ wbuf[0] = sdata & 0xFF;
+ wbuf[1] = sdata >> 8;
+ if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT,
+ wbuf, 2, rbuf, 2, NULL)) == 0) {
+ *rdata = (u_char)rbuf[0] | ((u_char)rbuf[1] << 8);
+ }
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+int
+ig4iic_smb_bwrite(device_t dev, u_char slave, char cmd,
+ u_char wcount, char *buf)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ error = smb_transaction(sc, cmd, 0,
+ buf, wcount, NULL, 0, NULL);
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+int
+ig4iic_smb_bread(device_t dev, u_char slave, char cmd,
+ u_char *countp_char, char *buf)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int rcount = *countp_char;
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, 0);
+ error = smb_transaction(sc, cmd, 0,
+ NULL, 0, buf, rcount, &rcount);
+ *countp_char = rcount;
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+int
+ig4iic_smb_trans(device_t dev, int slave, char cmd, int op,
+ char *wbuf, int wcount, char *rbuf, int rcount,
+ int *actualp)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ mtx_lock(&sc->mutex);
+
+ set_slave_addr(sc, slave, op);
+ error = smb_transaction(sc, cmd, op,
+ wbuf, wcount, rbuf, rcount, actualp);
+
+ mtx_unlock(&sc->mutex);
+ return (error);
+}
+
+/*
+ * Interrupt Operation
+ */
+static void
+ig4iic_intr(void *cookie)
+{
+ ig4iic_softc_t *sc = cookie;
+ uint32_t status;
+
+ mtx_lock(&sc->mutex);
+/* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/
+ status = reg_read(sc, IG4_REG_I2C_STA);
+ while (status & IG4_STATUS_RX_NOTEMPTY) {
+ sc->rbuf[sc->rnext & IG4_RBUFMASK] =
+ (uint8_t)reg_read(sc, IG4_REG_DATA_CMD);
+ ++sc->rnext;
+ status = reg_read(sc, IG4_REG_I2C_STA);
+ }
+ reg_read(sc, IG4_REG_CLR_INTR);
+ wakeup(sc);
+ mtx_unlock(&sc->mutex);
+}
+
+#define REGDUMP(sc, reg) \
+ device_printf(sc->dev, " %-23s %08x\n", #reg, reg_read(sc, reg))
+
+static void
+ig4iic_dump(ig4iic_softc_t *sc)
+{
+ device_printf(sc->dev, "ig4iic register dump:\n");
+ REGDUMP(sc, IG4_REG_CTL);
+ REGDUMP(sc, IG4_REG_TAR_ADD);
+ REGDUMP(sc, IG4_REG_SS_SCL_HCNT);
+ REGDUMP(sc, IG4_REG_SS_SCL_LCNT);
+ REGDUMP(sc, IG4_REG_FS_SCL_HCNT);
+ REGDUMP(sc, IG4_REG_FS_SCL_LCNT);
+ REGDUMP(sc, IG4_REG_INTR_STAT);
+ REGDUMP(sc, IG4_REG_INTR_MASK);
+ REGDUMP(sc, IG4_REG_RAW_INTR_STAT);
+ REGDUMP(sc, IG4_REG_RX_TL);
+ REGDUMP(sc, IG4_REG_TX_TL);
+ REGDUMP(sc, IG4_REG_I2C_EN);
+ REGDUMP(sc, IG4_REG_I2C_STA);
+ REGDUMP(sc, IG4_REG_TXFLR);
+ REGDUMP(sc, IG4_REG_RXFLR);
+ REGDUMP(sc, IG4_REG_SDA_HOLD);
+ REGDUMP(sc, IG4_REG_TX_ABRT_SOURCE);
+ REGDUMP(sc, IG4_REG_SLV_DATA_NACK);
+ REGDUMP(sc, IG4_REG_DMA_CTRL);
+ REGDUMP(sc, IG4_REG_DMA_TDLR);
+ REGDUMP(sc, IG4_REG_DMA_RDLR);
+ REGDUMP(sc, IG4_REG_SDA_SETUP);
+ REGDUMP(sc, IG4_REG_ENABLE_STATUS);
+ REGDUMP(sc, IG4_REG_COMP_PARAM1);
+ REGDUMP(sc, IG4_REG_COMP_VER);
+ REGDUMP(sc, IG4_REG_COMP_TYPE);
+ REGDUMP(sc, IG4_REG_CLK_PARMS);
+ REGDUMP(sc, IG4_REG_RESETS);
+ REGDUMP(sc, IG4_REG_GENERAL);
+ REGDUMP(sc, IG4_REG_SW_LTR_VALUE);
+ REGDUMP(sc, IG4_REG_AUTO_LTR_VALUE);
+}
+#undef REGDUMP
+
+DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL);
diff --git a/sys/dev/ichiic/ig4_pci.c b/sys/dev/ichiic/ig4_pci.c
new file mode 100644
index 000000000000..42c3664a1194
--- /dev/null
+++ b/sys/dev/ichiic/ig4_pci.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2014 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com> and was subsequently ported
+ * to FreeBSD by Michael Gmelin <freebsd@grem.de>
+ *
+ * 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 DragonFly Project 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 HOLDERS 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Intel fourth generation mobile cpus integrated I2C device, smbus driver.
+ *
+ * See ig4_reg.h for datasheet reference and notes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/errno.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/syslog.h>
+#include <sys/bus.h>
+
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/smbus/smbconf.h>
+
+#include "smbus_if.h"
+
+#include <dev/ichiic/ig4_reg.h>
+#include <dev/ichiic/ig4_var.h>
+
+static int ig4iic_pci_detach(device_t dev);
+
+#define PCI_CHIP_LYNXPT_LP_I2C_1 0x9c618086
+#define PCI_CHIP_LYNXPT_LP_I2C_2 0x9c628086
+
+static int
+ig4iic_pci_probe(device_t dev)
+{
+ switch(pci_get_devid(dev)) {
+ case PCI_CHIP_LYNXPT_LP_I2C_1:
+ device_set_desc(dev, "Intel Lynx Point-LP I2C Controller-1");
+ break;
+ case PCI_CHIP_LYNXPT_LP_I2C_2:
+ device_set_desc(dev, "Intel Lynx Point-LP I2C Controller-2");
+ break;
+ default:
+ return (ENXIO);
+ }
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ig4iic_pci_attach(device_t dev)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ bzero(sc, sizeof(*sc));
+
+ mtx_init(&sc->mutex, device_get_nameunit(dev), "ig4iic", MTX_DEF);
+
+ sc->dev = dev;
+ sc->regs_rid = PCIR_BAR(0);
+ sc->regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->regs_rid, RF_ACTIVE);
+ if (sc->regs_res == NULL) {
+ device_printf(dev, "unable to map registers\n");
+ ig4iic_pci_detach(dev);
+ return (ENXIO);
+ }
+ sc->intr_rid = 0;
+ if (pci_alloc_msi(dev, &sc->intr_rid)) {
+ device_printf(dev, "Using MSI\n");
+ }
+ sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->intr_rid, RF_SHAREABLE | RF_ACTIVE);
+ if (sc->intr_res == NULL) {
+ device_printf(dev, "unable to map interrupt\n");
+ ig4iic_pci_detach(dev);
+ return (ENXIO);
+ }
+ sc->pci_attached = 1;
+
+ error = ig4iic_attach(sc);
+ if (error)
+ ig4iic_pci_detach(dev);
+
+ return (error);
+}
+
+static int
+ig4iic_pci_detach(device_t dev)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ int error;
+
+ if (sc->pci_attached) {
+ error = ig4iic_detach(sc);
+ if (error)
+ return (error);
+ sc->pci_attached = 0;
+ }
+
+ if (sc->intr_res) {
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->intr_rid, sc->intr_res);
+ sc->intr_res = NULL;
+ }
+ if (sc->intr_rid != 0)
+ pci_release_msi(dev);
+ if (sc->regs_res) {
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ sc->regs_rid, sc->regs_res);
+ sc->regs_res = NULL;
+ }
+ mtx_destroy(&sc->mutex);
+
+ return (0);
+}
+
+static device_method_t ig4iic_pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ig4iic_pci_probe),
+ DEVMETHOD(device_attach, ig4iic_pci_attach),
+ DEVMETHOD(device_detach, ig4iic_pci_detach),
+
+ /* SMBus methods from ig4_smb.c */
+ DEVMETHOD(smbus_callback, ig4iic_smb_callback),
+ DEVMETHOD(smbus_quick, ig4iic_smb_quick),
+ DEVMETHOD(smbus_sendb, ig4iic_smb_sendb),
+ DEVMETHOD(smbus_recvb, ig4iic_smb_recvb),
+ DEVMETHOD(smbus_writeb, ig4iic_smb_writeb),
+ DEVMETHOD(smbus_writew, ig4iic_smb_writew),
+ DEVMETHOD(smbus_readb, ig4iic_smb_readb),
+ DEVMETHOD(smbus_readw, ig4iic_smb_readw),
+ DEVMETHOD(smbus_pcall, ig4iic_smb_pcall),
+ DEVMETHOD(smbus_bwrite, ig4iic_smb_bwrite),
+ DEVMETHOD(smbus_bread, ig4iic_smb_bread),
+ DEVMETHOD(smbus_trans, ig4iic_smb_trans),
+
+ DEVMETHOD_END
+};
+
+static driver_t ig4iic_pci_driver = {
+ "ig4iic",
+ ig4iic_pci_methods,
+ sizeof(struct ig4iic_softc)
+};
+
+static devclass_t ig4iic_pci_devclass;
+
+DRIVER_MODULE(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0);
+MODULE_DEPEND(ig4iic, pci, 1, 1, 1);
+MODULE_DEPEND(ig4iic, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(ig4iic, 1);
diff --git a/sys/dev/ichiic/ig4_reg.h b/sys/dev/ichiic/ig4_reg.h
new file mode 100644
index 000000000000..c87d1d1e9fd2
--- /dev/null
+++ b/sys/dev/ichiic/ig4_reg.h
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2014 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com> and was subsequently ported
+ * to FreeBSD by Michael Gmelin <freebsd@grem.de>
+ *
+ * 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 DragonFly Project 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 HOLDERS 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$
+ */
+/*
+ * Intel fourth generation mobile cpus integrated I2C device.
+ *
+ * Datasheet reference: Section 22.
+ *
+ * http://www.intel.com/content/www/us/en/processors/core/4th-gen-core-family-mobile-i-o-datasheet.html?wapkw=datasheets+4th+generation
+ *
+ * This is a from-scratch driver under the BSD license using the Intel data
+ * sheet and the linux driver for reference. All code is freshly written
+ * without referencing the linux driver code. However, during testing
+ * I am also using the linux driver code as a reference to help resolve any
+ * issues that come. These will be specifically documented in the code.
+ *
+ * Please see protocol notes in section 5.21. This controller is an I2C
+ * master only and cannot act as a slave. The IO voltage should be set by
+ * the BIOS. Standard (100Kb/s) and Fast (400Kb/s) and fast mode plus
+ * (1MB/s) is supported. High speed mode (3.4 MB/s) is NOT supported.
+ */
+
+#ifndef _BUS_SMBUS_INTELGEN4_IG4_REG_H_
+#define _BUS_SMBUS_INTELGEN4_IG4_REG_H_
+
+/*
+ * 22.2 MMIO registers can be accessed through BAR0 in PCI mode or through
+ * BAR1 when in ACPI mode.
+ *
+ * Register width is 32-bits
+ *
+ * 22.2 Default Values on device reset are 0 except as specified here:
+ * TAR_ADD 0x00000055
+ * SS_SCL_HCNT 0x00000264
+ * SS_SCL_LCNT 0x000002C2
+ * FS_SCL_HCNT 0x0000006E
+ * FS_SCL_LCNT 0x000000CF
+ * INTR_MASK 0x000008FF
+ * I2C_STA 0x00000006
+ * SDA_HOLD 0x00000001
+ * SDA_SETUP 0x00000064
+ * COMP_PARAM1 0x00FFFF6E
+ * COMP_VER 0x3131352A
+ */
+
+#define IG4_REG_CTL 0x0000 /* RW Control Register */
+#define IG4_REG_TAR_ADD 0x0004 /* RW Target Address */
+#define IG4_REG_DATA_CMD 0x0010 /* RW Data Buffer and Command */
+#define IG4_REG_SS_SCL_HCNT 0x0014 /* RW Std Speed clock High Count */
+#define IG4_REG_SS_SCL_LCNT 0x0018 /* RW Std Speed clock Low Count */
+#define IG4_REG_FS_SCL_HCNT 0x001C /* RW Fast Speed clock High Count */
+#define IG4_REG_FS_SCL_LCNT 0x0020 /* RW Fast Speed clock Low Count */
+#define IG4_REG_INTR_STAT 0x002C /* RO Interrupt Status */
+#define IG4_REG_INTR_MASK 0x0030 /* RW Interrupt Mask */
+#define IG4_REG_RAW_INTR_STAT 0x0034 /* RO Raw Interrupt Status */
+#define IG4_REG_RX_TL 0x0038 /* RW Receive FIFO Threshold */
+#define IG4_REG_TX_TL 0x003C /* RW Transmit FIFO Threshold */
+#define IG4_REG_CLR_INTR 0x0040 /* RO Clear Interrupt */
+#define IG4_REG_CLR_RX_UNDER 0x0044 /* RO Clear RX_Under Interrupt */
+#define IG4_REG_CLR_RX_OVER 0x0048 /* RO Clear RX_Over Interrupt */
+#define IG4_REG_CLR_TX_OVER 0x004C /* RO Clear TX_Over Interrupt */
+#define IG4_REG_CLR_TX_ABORT 0x0054 /* RO Clear TX_Abort Interrupt */
+#define IG4_REG_CLR_ACTIVITY 0x005C /* RO Clear Activity Interrupt */
+#define IG4_REG_CLR_STOP_DET 0x0060 /* RO Clear STOP Detection Int */
+#define IG4_REG_CLR_START_DET 0x0064 /* RO Clear START Detection Int */
+#define IG4_REG_CLR_GEN_CALL 0x0068 /* RO Clear General Call Interrupt */
+#define IG4_REG_I2C_EN 0x006C /* RW I2C Enable */
+#define IG4_REG_I2C_STA 0x0070 /* RO I2C Status */
+#define IG4_REG_TXFLR 0x0074 /* RO Transmit FIFO Level */
+#define IG4_REG_RXFLR 0x0078 /* RO Receive FIFO Level */
+#define IG4_REG_SDA_HOLD 0x007C /* RW SDA Hold Time Length */
+#define IG4_REG_TX_ABRT_SOURCE 0x0080 /* RO Transmit Abort Source */
+#define IG4_REG_SLV_DATA_NACK 0x0084 /* RW General Slave Data NACK */
+#define IG4_REG_DMA_CTRL 0x0088 /* RW DMA Control */
+#define IG4_REG_DMA_TDLR 0x008C /* RW DMA Transmit Data Level */
+#define IG4_REG_DMA_RDLR 0x0090 /* RW DMA Receive Data Level */
+#define IG4_REG_SDA_SETUP 0x0094 /* RW SDA Setup */
+#define IG4_REG_ENABLE_STATUS 0x009C /* RO Enable Status */
+#define IG4_REG_COMP_PARAM1 0x00F4 /* RO Component Parameter */
+#define IG4_REG_COMP_VER 0x00F8 /* RO Component Version */
+#define IG4_REG_COMP_TYPE 0x00FC /* RO Probe width/endian? (linux) */
+#define IG4_REG_CLK_PARMS 0x0800 /* RW Clock Parameters */
+#define IG4_REG_RESETS 0x0804 /* RW Reset Register */
+#define IG4_REG_GENERAL 0x0808 /* RW General Register */
+#define IG4_REG_SW_LTR_VALUE 0x0810 /* RW SW LTR Value */
+#define IG4_REG_AUTO_LTR_VALUE 0x0814 /* RW Auto LTR Value */
+
+/*
+ * CTL - Control Register 22.2.1
+ * Default Value: 0x0000007F.
+ *
+ * RESTARTEN - RW Restart Enable
+ * 10BIT - RW Controller operates in 10-bit mode, else 7-bit
+ *
+ * NOTE: When restart is disabled the controller is incapable of
+ * performing the following functions:
+ *
+ * Sending a START Byte
+ * Performing any high-speed mode op
+ * Performing direction changes in combined format mode
+ * Performing a read operation with a 10-bit address
+ *
+ * Attempting to perform the above operations will result in the
+ * TX_ABORT bit being set in RAW_INTR_STAT.
+ */
+#define IG4_CTL_SLAVE_DISABLE 0x0040 /* snarfed from linux */
+#define IG4_CTL_RESTARTEN 0x0020 /* Allow Restart when master */
+#define IG4_CTL_10BIT 0x0010 /* ctlr accepts 10-bit addresses */
+#define IG4_CTL_SPEED_FAST 0x0004 /* snarfed from linux */
+#define IG4_CTL_SPEED_STD 0x0002 /* snarfed from linux */
+#define IG4_CTL_MASTER 0x0001 /* snarfed from linux */
+
+/*
+ * TAR_ADD - Target Address Register 22.2.2
+ * Default Value: 0x00000055F
+ *
+ * 10BIT - RW controller starts its transfers in 10-bit
+ * address mode, else 7-bit.
+ *
+ * SPECIAL - RW Indicates whether software performs a General Call
+ * or START BYTE command.
+ *
+ * 0 Ignore GC_OR_START and use TAR address.
+ *
+ * 1 Perform special I2C Command based on GC_OR_START.
+ *
+ * GC_OR_START - RW (only if SPECIAL is set)
+ *
+ * 0 General Call Address. After issuing a General Call,
+ * only writes may be performed. Attempting to issue
+ * a read command results in IX_ABRT in RAW_INTR_STAT.
+ * The controller remains in General Call mode until
+ * bit 11 (SPECIAL) is cleared.
+ *
+ * 1 START BYTE.
+ *
+ *
+ * IC_TAR - RW when transmitting a general call, these bits are
+ * ignored. To generate a START BYTE, the address
+ * needs to be written into these bits once.
+ *
+ * This register should only be updated when the IIC is disabled (I2C_ENABLE=0)
+ */
+#define IG4_TAR_10BIT 0x1000 /* start xfer in 10-bit mode */
+#define IG4_TAR_SPECIAL 0x0800 /* Perform special command */
+#define IG4_TAR_GC_OR_START 0x0400 /* General Call or Start */
+#define IG4_TAR_ADDR_MASK 0x03FF /* Target address */
+
+/*
+ * TAR_DATA_CMD - Data Buffer and Command Register 22.2.3
+ *
+ * RESTART - RW This bit controls whether a forced RESTART is
+ * issued before the byte is sent or received.
+ *
+ * 0 If not set a RESTART is only issued if the tranfer
+ * direction is changing from the previous command.
+ *
+ * 1 A RESTART is issued before the byte is sent or
+ * received, regardless of whether or not the transfer
+ * direction is changing from the previous command.
+ *
+ * STOP - RW This bit controls whether a STOP is issued after
+ * the byte is sent or received.
+ *
+ * 0 STOP is not issued after this byte, regardless
+ * of whether or not the Tx FIFO is empty.
+ *
+ * 1 STOP is issued after this byte, regardless of
+ * whether or not the Tx FIFO is empty. If the
+ * Tx FIFO is not empty the master immediately tries
+ * to start a new transfer by issuing a START and
+ * arbitrating for the bus.
+ *
+ * i.e. the STOP is issued along with this byte,
+ * within the write stream.
+ *
+ * COMMAND - RW Control whether a read or write is performed.
+ *
+ * 0 WRITE
+ *
+ * 1 READ
+ *
+ * DATA (7:0) - RW Contains the data to be transmitted or received
+ * on the I2C bus.
+ *
+ * NOTE: Writing to this register causes a START + slave + RW to be
+ * issued if the direction has changed or the last data byte was
+ * sent with a STOP.
+ *
+ * NOTE: We control termination? so this register must be written
+ * for each byte we wish to receive. We can then drain the
+ * receive FIFO.
+ */
+
+#define IG4_DATA_RESTART 0x0400 /* Force RESTART */
+#define IG4_DATA_STOP 0x0200 /* Force STOP[+START] */
+#define IG4_DATA_COMMAND_RD 0x0100 /* bus direction 0=write 1=read */
+#define IG4_DATA_MASK 0x00FF
+
+/*
+ * SS_SCL_HCNT - Standard Speed Clock High Count Register 22.2.4
+ * SS_SCL_LCNT - Standard Speed Clock Low Count Register 22.2.5
+ * FS_SCL_HCNT - Fast Speed Clock High Count Register 22.2.6
+ * FS_SCL_LCNT - Fast Speed Clock Low Count Register 22.2.7
+ *
+ * COUNT (15:0) - Set the period count to a value between 6 and
+ * 65525.
+ */
+#define IG4_SCL_CLOCK_MASK 0xFFFFU /* count bits in register */
+
+/*
+ * INTR_STAT - (RO) Interrupt Status Register 22.2.8
+ * INTR_MASK - (RW) Interrupt Mask Register 22.2.9
+ * RAW_INTR_STAT- (RO) Raw Interrupt Status Register 22.2.10
+ *
+ * GEN_CALL Set only when a general call (broadcast) address
+ * is received and acknowleged, stays set until
+ * cleared by reading CLR_GEN_CALL.
+ *
+ * START_DET Set when a START or RESTART condition has occurred
+ * on the interface.
+ *
+ * STOP_DET Set when a STOP condition has occurred on the
+ * interface.
+ *
+ * ACTIVITY Set by any activity on the interface. Cleared
+ * by reading CLR_ACTIVITY or CLR_INTR.
+ *
+ * TX_ABRT Indicates the controller as a transmitter is
+ * unable to complete the intended action. When set,
+ * the controller will hold the TX FIFO in a reset
+ * state (flushed) until CLR_TX_ABORT is read to
+ * clear the condition. Once cleared, the TX FIFO
+ * will be available again.
+ *
+ * TX_EMPTY Indicates that the transmitter is at or below
+ * the specified TX_TL threshold. Automatically
+ * cleared by HW when the buffer level goes above
+ * the threshold.
+ *
+ * TX_OVER Indicates that the processer attempted to write
+ * to the TX FIFO while the TX FIFO was full. Cleared
+ * by reading CLR_TX_OVER.
+ *
+ * RX_FULL Indicates that the receive FIFO has reached or
+ * exceeded the specified RX_TL threshold. Cleared
+ * by HW when the cpu drains the FIFO to below the
+ * threshold.
+ *
+ * RX_OVER Indicates that the receive FIFO was unable to
+ * accept new data and data was lost. Cleared by
+ * reading CLR_RX_OVER.
+ *
+ * RX_UNDER Indicates that the cpu attempted to read data
+ * from the receive buffer while the RX FIFO was
+ * empty. Cleared by reading CLR_RX_UNDER.
+ *
+ * NOTES ON RAW_INTR_STAT:
+ *
+ * This register can be used to monitor the GEN_CALL, START_DET,
+ * STOP_DET, ACTIVITY, TX_ABRT, TX_EMPTY, TX_OVER, RX_FULL, RX_OVER,
+ * and RX_UNDER bits. The documentation is a bit unclear but presumably
+ * this is the unlatched version.
+ *
+ * Code should test FIFO conditions using the I2C_STA (status) register,
+ * not the interrupt status registers.
+ */
+
+#define IG4_INTR_GEN_CALL 0x0800
+#define IG4_INTR_START_DET 0x0400
+#define IG4_INTR_STOP_DET 0x0200
+#define IG4_INTR_ACTIVITY 0x0100
+#define IG4_INTR_TX_ABRT 0x0040
+#define IG4_INTR_TX_EMPTY 0x0010
+#define IG4_INTR_TX_OVER 0x0008
+#define IG4_INTR_RX_FULL 0x0004
+#define IG4_INTR_RX_OVER 0x0002
+#define IG4_INTR_RX_UNDER 0x0001
+
+/*
+ * RX_TL - (RW) Receive FIFO Threshold Register 22.2.11
+ * TX_TL - (RW) Transmit FIFO Threshold Register 22.2.12
+ *
+ * Specify the receive and transmit FIFO threshold register. The
+ * FIFOs have 16 elements. The valid range is 0-15. Setting a
+ * value greater than 15 causes the actual value to be the maximum
+ * depth of the FIFO.
+ *
+ * Generally speaking since everything is messaged, we can use a
+ * mid-level setting for both parameters and (e.g.) fully drain the
+ * receive FIFO on the STOP_DET condition to handle loose ends.
+ */
+#define IG4_FIFO_MASK 0x00FF
+#define IG4_FIFO_LIMIT 16
+
+/*
+ * CLR_INTR - (RO) Clear Interrupt Register 22.2.13
+ * CLR_RX_UNDER - (RO) Clear Interrupt Register (specific) 22.2.14
+ * CLR_RX_OVER - (RO) Clear Interrupt Register (specific) 22.2.15
+ * CLR_TX_OVER - (RO) Clear Interrupt Register (specific) 22.2.16
+ * CLR_TX_ABORT - (RO) Clear Interrupt Register (specific) 22.2.17
+ * CLR_ACTIVITY - (RO) Clear Interrupt Register (specific) 22.2.18
+ * CLR_STOP_DET - (RO) Clear Interrupt Register (specific) 22.2.19
+ * CLR_START_DET- (RO) Clear Interrupt Register (specific) 22.2.20
+ * CLR_GEN_CALL - (RO) Clear Interrupt Register (specific) 22.2.21
+ *
+ * CLR_* specific operations clear the appropriate bit in the
+ * RAW_INTR_STAT register. Intel does not really document whether
+ * these operations clear the normal interrupt status register.
+ *
+ * CLR_INTR clears bits in the normal interrupt status register and
+ * presumably also the raw(?) register? Intel is again unclear.
+ *
+ * NOTE: CLR_INTR only clears software-clearable interrupts. Hardware
+ * clearable interrupts are controlled entirely by the hardware.
+ * CLR_INTR also clears the TX_ABRT_SOURCE register.
+ *
+ * NOTE: CLR_TX_ABORT also clears the TX_ABRT_SOURCE register and releases
+ * the TX FIFO from its flushed/reset state, allowing more writes
+ * to the TX FIFO.
+ *
+ * NOTE: CLR_ACTIVITY has no effect if the I2C bus is still active.
+ * Intel documents that the bit is automatically cleared when
+ * there is no further activity on the bus.
+ */
+#define IG4_CLR_BIT 0x0001 /* Reflects source */
+
+/*
+ * I2C_EN - (RW) I2C Enable Register 22.2.22
+ *
+ * ABORT Software can abort an I2C transfer by setting this
+ * bit. Hardware will clear the bit once the STOP has
+ * been detected. This bit can only be set while the
+ * I2C interface is enabled.
+ *
+ * I2C_ENABLE Enable the controller, else disable it.
+ * (Use I2C_ENABLE_STATUS to poll enable status
+ * & wait for changes)
+ */
+#define IG4_I2C_ABORT 0x0002
+#define IG4_I2C_ENABLE 0x0001
+
+/*
+ * I2C_STA - (RO) I2C Status Register 22.2.23
+ */
+#define IG4_STATUS_ACTIVITY 0x0020 /* Controller is active */
+#define IG4_STATUS_RX_FULL 0x0010 /* RX FIFO completely full */
+#define IG4_STATUS_RX_NOTEMPTY 0x0008 /* RX FIFO not empty */
+#define IG4_STATUS_TX_EMPTY 0x0004 /* TX FIFO completely empty */
+#define IG4_STATUS_TX_NOTFULL 0x0002 /* TX FIFO not full */
+#define IG4_STATUS_I2C_ACTIVE 0x0001 /* I2C bus is active */
+
+/*
+ * TXFLR - (RO) Transmit FIFO Level Register 22.2.24
+ * RXFLR - (RO) Receive FIFO Level Register 22.2.25
+ *
+ * Read the number of entries currently in the Transmit or Receive
+ * FIFOs. Note that for some reason the mask is 9 bits instead of
+ * the 8 bits the fill level controls.
+ */
+#define IG4_FIFOLVL_MASK 0x001F
+
+/*
+ * SDA_HOLD - (RW) SDA Hold Time Length Register 22.2.26
+ *
+ * Set the SDA hold time length register in I2C clocks.
+ */
+#define IG4_SDA_HOLD_MASK 0x00FF
+
+/*
+ * TX_ABRT_SOURCE- (RO) Transmit Abort Source Register 22.2.27
+ *
+ * Indicates the cause of a transmit abort. This can indicate a
+ * software programming error or a device expected address width
+ * mismatch or other issues. The NORESTART conditions and GENCALL_NOACK
+ * can only occur if a programming error was made in the driver software.
+ *
+ * In particular, it should be possible to detect whether any devices
+ * are on the bus by observing the GENCALL_READ status, and it might
+ * be possible to detect ADDR7 vs ADDR10 mismatches.
+ */
+#define IG4_ABRTSRC_TRANSFER 0x00010000 /* Abort initiated by user */
+#define IG4_ABRTSRC_ARBLOST 0x00001000 /* Arbitration lost */
+#define IG4_ABRTSRC_NORESTART_10 0x00000400 /* RESTART disabled */
+#define IG4_ABRTSRC_NORESTART_START 0x00000200 /* RESTART disabled */
+#define IG4_ABRTSRC_ACKED_START 0x00000080 /* Improper acked START */
+#define IG4_ABRTSRC_GENCALL_NOACK 0x00000020 /* Improper GENCALL */
+#define IG4_ABRTSRC_GENCALL_READ 0x00000010 /* Nobody acked GENCALL */
+#define IG4_ABRTSRC_TXNOACK_DATA 0x00000008 /* data phase no ACK */
+#define IG4_ABRTSRC_TXNOACK_ADDR10_2 0x00000004 /* addr10/1 phase no ACK */
+#define IG4_ABRTSRC_TXNOACK_ADDR10_1 0x00000002 /* addr10/2 phase no ACK */
+#define IG4_ABRTSRC_TXNOACK_ADDR7 0x00000001 /* addr7 phase no ACK */
+
+/*
+ * SLV_DATA_NACK - (RW) Generate Slave DATA NACK Register 22.2.28
+ *
+ * When the controller is a receiver a NACK can be generated on
+ * receipt of data.
+ *
+ * NACK_GENERATE Set to 0 for normal NACK/ACK generation.
+ * Set to 1 to generate a NACK after next data
+ * byte received.
+ *
+ */
+#define IG4_NACK_GENERATE 0x0001
+
+/*
+ * DMA_CTRL - (RW) DMA Control Register 22.2.29
+ *
+ * Enables DMA on the transmit and/or receive DMA channel.
+ */
+#define IG4_TX_DMA_ENABLE 0x0002
+#define IG4_RX_DMA_ENABLE 0x0001
+
+/*
+ * DMA_TDLR - (RW) DMA Transmit Data Level Register 22.2.30
+ * DMA_RDLR - (RW) DMA Receive Data Level Register 22.2.31
+ *
+ * Similar to RX_TL and TX_TL but controls when a DMA burst occurs
+ * to empty or fill the FIFOs. Use the same IG4_FIFO_MASK and
+ * IG4_FIFO_LIMIT defines for RX_RL and TX_TL.
+ */
+/* empty */
+
+/*
+ * SDA_SETUP - (RW) SDA Setup Time Length Register 22.2.32
+ *
+ * Set the SDA setup time length register in I2C clocks.
+ * The register must be programmed with a value >=2.
+ * (Defaults to 0x64).
+ */
+#define IG4_SDA_SETUP_MASK 0x00FF
+
+/*
+ * ACK_GEN_CALL - (RW) ACK General Call Register 22.2.33
+ *
+ * Control whether the controller responds with a ACK or NACK when
+ * it receives an I2C General Call address.
+ *
+ * If set to 0 a NACK is generated and a General Call interrupt is
+ * NOT generated. Otherwise an ACK + interrupt is generated.
+ */
+#define IG4_ACKGC_ACK 0x0001
+
+/*
+ * ENABLE_STATUS - (RO) Enable Status Registger 22.2.34
+ *
+ * DATA_LOST - Indicates that a slave receiver operation has
+ * been aborted with at least one data byte received
+ * from a transfer due to the I2C controller being
+ * disabled (IG4_I2C_ENABLE -> 0)
+ *
+ * ENABLED - Intel documentation is lacking but I assume this
+ * is a reflection of the IG4_I2C_ENABLE bit in the
+ * I2C_EN register.
+ *
+ */
+#define IG4_ENASTAT_DATA_LOST 0x0004
+#define IG4_ENASTAT_ENABLED 0x0001
+
+/*
+ * COMP_PARAM1 - (RO) Component Parameter Register 22.2.35
+ * Default Value 0x00FFFF6E
+ *
+ * VALID - Intel documentation is unclear but I believe this
+ * must be read as a 1 to indicate that the rest of
+ * the bits in the register are valid.
+ *
+ * HASDMA - Indicates that the chip is DMA-capable. Presumably
+ * in certain virtualization cases the chip might be
+ * set to not be DMA-capable.
+ *
+ * INTR_IO - Indicates that all interrupts are combined to
+ * generate one interrupt. If not set, interrupts
+ * are individual (more virtualization stuff?)
+ *
+ * HCCNT_RO - Indicates that the clock timing registers are
+ * RW. If not set, the registers are RO.
+ * (more virtualization stuff).
+ *
+ * MAXSPEED - Indicates the maximum speed supported.
+ *
+ * DATAW - Indicates the internal bus width in bits.
+ */
+#define IG4_PARAM1_TXFIFO_DEPTH(v) (((v) >> 16) & 0xFF)
+#define IG4_PARAM1_RXFIFO_DEPTH(v) (((v) >> 8) & 0xFF)
+#define IG4_PARAM1_CONFIG_VALID 0x00000080
+#define IG4_PARAM1_CONFIG_HASDMA 0x00000040
+#define IG4_PARAM1_CONFIG_INTR_IO 0x00000020
+#define IG4_PARAM1_CONFIG_HCCNT_RO 0x00000010
+#define IG4_PARAM1_CONFIG_MAXSPEED_MASK 0x0000000C
+#define IG4_PARAM1_CONFIG_DATAW_MASK 0x00000003
+
+#define IG4_CONFIG_MAXSPEED_RESERVED00 0x00000000
+#define IG4_CONFIG_MAXSPEED_STANDARD 0x00000004
+#define IG4_CONFIG_MAXSPEED_FAST 0x00000008
+#define IG4_CONFIG_MAXSPEED_HIGH 0x0000000C
+
+#define IG4_CONFIG_DATAW_8 0x00000000
+#define IG4_CONFIG_DATAW_16 0x00000001
+#define IG4_CONFIG_DATAW_32 0x00000002
+#define IG4_CONFIG_DATAW_RESERVED11 0x00000003
+
+/*
+ * COMP_VER - (RO) Component Version Register 22.2.36
+ * Default Value 0x3131352A
+ *
+ * Contains the chip version number. All 32 bits.
+ */
+#define IG4_COMP_VER 0x3131352A
+
+/*
+ * COMP_TYPE - (RO) (linux) Endian and bus width probe
+ *
+ * Read32 from this register and test against IG4_COMP_TYPE
+ * to determine the bus width. e.g. 01404457 = endian-reversed,
+ * and 00000140 or 00004457 means internal 16-bit bus (?).
+ *
+ * This register is not in the intel documentation, I pulled it
+ * from the linux driver i2c-designware-core.c.
+ */
+#define IG4_COMP_TYPE 0x44570140
+
+/*
+ * RESETS - (RW) Resets Register 22.2.37
+ *
+ * Used to reset the I2C host controller by SW. There is no timing
+ * requirement, software can assert and de-assert in back-to-back
+ * transactions.
+ *
+ * 00 I2C host controller is NOT in reset.
+ * 01 (reserved)
+ * 10 (reserved)
+ * 11 I2C host controller is in reset.
+ */
+#define IG4_RESETS_ASSERT 0x0003
+#define IG4_RESETS_DEASSERT 0x0000
+
+/*
+ * GENERAL - (RW) General Reigster 22.2.38
+ *
+ * IOVOLT 0=1.8V 1=3.3V
+ *
+ * LTR 0=Auto 1=SW
+ *
+ * In Auto mode the BIOS will write to the host controller's
+ * AUTO LTR Value register (offset 0x0814) with the active
+ * state LTR value, and will write to the SW LTR Value register
+ * (offset 0x0810) with the idle state LTR value.
+ *
+ * In SW mode the SW will write to the host controller SW LTR
+ * value (offset 0x0810). It is the SW responsibility to update
+ * the LTR with the appropriate value.
+ */
+#define IG4_GENERAL_IOVOLT3_3 0x0008
+#define IG4_GENERAL_SWMODE 0x0004
+
+/*
+ * SW_LTR_VALUE - (RW) SW LTR Value Register 22.2.39
+ * AUTO_LTR_VALUE - (RW) SW LTR Value Register 22.2.40
+ *
+ * Default value is 0x00000800 which means the best possible
+ * service/response time.
+ *
+ * It isn't quite clear how the snooping works. There are two scale
+ * bits for both sets but two of the four codes are reserved. The
+ * *SNOOP_VALUE() is specified as a 10-bit latency value. If 0, it
+ * indicates that the device cannot tolerate any delay and needs the
+ * best possible service/response time.
+ *
+ * I think this is for snooping (testing) the I2C bus. The lowest
+ * delay (0) probably runs the controller polling at a high, power hungry
+ * rate. But I dunno.
+ */
+#define IG4_SWLTR_NSNOOP_REQ 0x80000000 /* (ro) */
+#define IG4_SWLTR_NSNOOP_SCALE_MASK 0x1C000000 /* (ro) */
+#define IG4_SWLTR_NSNOOP_SCALE_1US 0x08000000 /* (ro) */
+#define IG4_SWLTR_NSNOOP_SCALE_32US 0x0C000000 /* (ro) */
+#define IG4_SWLTR_NSNOOP_VALUE_DECODE(v) (((v) >> 16) & 0x3F)
+#define IG4_SWLTR_NSNOOP_VALUE_ENCODE(v) (((v) & 0x3F) << 16)
+
+#define IG4_SWLTR_SNOOP_REQ 0x00008000 /* (rw) */
+#define IG4_SWLTR_SNOOP_SCALE_MASK 0x00001C00 /* (rw) */
+#define IG4_SWLTR_SNOOP_SCALE_1US 0x00000800 /* (rw) */
+#define IG4_SWLTR_SNOOP_SCALE_32US 0x00000C00 /* (rw) */
+#define IG4_SWLTR_SNOOP_VALUE_DECODE(v) ((v) & 0x3F)
+#define IG4_SWLTR_SNOOP_VALUE_ENCODE(v) ((v) & 0x3F)
+
+#endif
diff --git a/sys/dev/ichiic/ig4_var.h b/sys/dev/ichiic/ig4_var.h
new file mode 100644
index 000000000000..6c910559b7ef
--- /dev/null
+++ b/sys/dev/ichiic/ig4_var.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2014 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com> and was subsequently ported
+ * to FreeBSD by Michael Gmelin <freebsd@grem.de>
+ *
+ * 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 DragonFly Project 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 HOLDERS 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$
+ */
+
+#ifndef _BUS_SMBUS_INTELGEN4_IG4_VAR_H_
+#define _BUS_SMBUS_INTELGEN4_IG4_VAR_H_
+
+#include "bus_if.h"
+#include "device_if.h"
+#include "pci_if.h"
+#include "smbus_if.h"
+
+#define IG4_RBUFSIZE 128
+#define IG4_RBUFMASK (IG4_RBUFSIZE - 1)
+
+enum ig4_op { IG4_IDLE, IG4_READ, IG4_WRITE };
+
+struct ig4iic_softc {
+ device_t dev;
+ struct intr_config_hook enum_hook;
+ device_t smb;
+ struct resource *regs_res;
+ int regs_rid;
+ struct resource *intr_res;
+ int intr_rid;
+ void *intr_handle;
+ int intr_type;
+ enum ig4_op op;
+ int cmd;
+ int rnext;
+ int rpos;
+ char rbuf[IG4_RBUFSIZE];
+ int error;
+ uint8_t last_slave;
+ int pci_attached : 1;
+ int use_10bit : 1;
+ int slave_valid : 1;
+ int read_started : 1;
+ int write_started : 1;
+ struct mtx mutex;
+};
+
+typedef struct ig4iic_softc ig4iic_softc_t;
+
+/* Attach/Detach called from ig4iic_pci_*() */
+int ig4iic_attach(ig4iic_softc_t *sc);
+int ig4iic_detach(ig4iic_softc_t *sc);
+
+/* SMBus methods */
+extern smbus_callback_t ig4iic_smb_callback;
+extern smbus_quick_t ig4iic_smb_quick;
+extern smbus_sendb_t ig4iic_smb_sendb;
+extern smbus_recvb_t ig4iic_smb_recvb;
+extern smbus_writeb_t ig4iic_smb_writeb;
+extern smbus_writew_t ig4iic_smb_writew;
+extern smbus_readb_t ig4iic_smb_readb;
+extern smbus_readw_t ig4iic_smb_readw;
+extern smbus_pcall_t ig4iic_smb_pcall;
+extern smbus_bwrite_t ig4iic_smb_bwrite;
+extern smbus_bread_t ig4iic_smb_bread;
+extern smbus_trans_t ig4iic_smb_trans;
+
+#endif
diff --git a/sys/dev/ichsmb/ichsmb_pci.c b/sys/dev/ichsmb/ichsmb_pci.c
index ae8b17904a81..00ba2c3747ea 100644
--- a/sys/dev/ichsmb/ichsmb_pci.c
+++ b/sys/dev/ichsmb/ichsmb_pci.c
@@ -5,7 +5,7 @@
* Copyright (c) 2000 Whistle Communications, Inc.
* All rights reserved.
* Author: Archie Cobbs <archie@freebsd.org>
- *
+ *
* Subject to the following obligations and disclaimer of warranty, use and
* redistribution of this software, in source or object code forms, with or
* without modifications are expressly permitted by Whistle Communications;
@@ -16,7 +16,7 @@
* Communications, Inc. trademarks, including the mark "WHISTLE
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
* such appears in the above copyright notice or in the software.
- *
+ *
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
@@ -91,6 +91,7 @@ __FBSDID("$FreeBSD$");
#define ID_LPTLP 0x9c228086
#define ID_WCPT 0x8ca28086
#define ID_WCPTLP 0x9ca28086
+#define ID_WELLSBURG 0x8d228086
#define PCIS_SERIALBUS_SMBUS_PROGIF 0x00
@@ -212,6 +213,9 @@ ichsmb_pci_probe(device_t dev)
case ID_COLETOCRK:
device_set_desc(dev, "Intel Coleto Creek SMBus controller");
break;
+ case ID_WELLSBURG:
+ device_set_desc(dev, "Intel Wellsburg SMBus controller");
+ break;
default:
return (ENXIO);
}
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index 7ac1deaa1d23..9c57aedd3a55 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -159,8 +159,8 @@ static void ndis_tick (void *);
static void ndis_ticktask (device_object *, void *);
static int ndis_raw_xmit (struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void ndis_update_mcast (struct ifnet *ifp);
-static void ndis_update_promisc (struct ifnet *ifp);
+static void ndis_update_mcast (struct ieee80211com *);
+static void ndis_update_promisc (struct ieee80211com *);
static void ndis_start (struct ifnet *);
static void ndis_starttask (device_object *, void *);
static void ndis_resettask (device_object *, void *);
@@ -738,6 +738,8 @@ ndis_attach(dev)
ifp->if_ioctl = ndis_ioctl_80211;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_DS;
ic->ic_caps = IEEE80211_C_8023ENCAP |
@@ -1771,15 +1773,15 @@ ndis_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
}
static void
-ndis_update_mcast(struct ifnet *ifp)
+ndis_update_mcast(struct ieee80211com *ic)
{
- struct ndis_softc *sc = ifp->if_softc;
+ struct ndis_softc *sc = ic->ic_softc;
ndis_setmulti(sc);
}
static void
-ndis_update_promisc(struct ifnet *ifp)
+ndis_update_promisc(struct ieee80211com *ic)
{
/* not supported */
}
diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c
index 04c33639f59b..d3eb85e8f188 100644
--- a/sys/dev/ipw/if_ipw.c
+++ b/sys/dev/ipw/if_ipw.c
@@ -286,6 +286,8 @@ ipw_attach(device_t dev)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_DS;
@@ -751,11 +753,8 @@ ipw_release(struct ipw_softc *sc)
}
if (sc->tbd_dmat != NULL) {
- if (sc->stbd_list != NULL) {
- bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map);
- bus_dmamem_free(sc->tbd_dmat, sc->tbd_list,
- sc->tbd_map);
- }
+ bus_dmamap_unload(sc->tbd_dmat, sc->tbd_map);
+ bus_dmamem_free(sc->tbd_dmat, sc->tbd_list, sc->tbd_map);
bus_dma_tag_destroy(sc->tbd_dmat);
}
diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c
index b6de4b69e7af..fecbe89c4562 100644
--- a/sys/dev/iwi/if_iwi.c
+++ b/sys/dev/iwi/if_iwi.c
@@ -154,7 +154,7 @@ static void iwi_node_free(struct ieee80211_node *);
static void iwi_media_status(struct ifnet *, struct ifmediareq *);
static int iwi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void iwi_wme_init(struct iwi_softc *);
-static int iwi_wme_setparams(struct iwi_softc *, struct ieee80211com *);
+static int iwi_wme_setparams(struct iwi_softc *);
static void iwi_update_wme(void *, int);
static int iwi_wme_update(struct ieee80211com *);
static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t);
@@ -364,6 +364,8 @@ iwi_attach(device_t dev)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -1057,8 +1059,9 @@ iwi_wme_init(struct iwi_softc *sc)
}
static int
-iwi_wme_setparams(struct iwi_softc *sc, struct ieee80211com *ic)
+iwi_wme_setparams(struct iwi_softc *sc)
{
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
const struct wmeParams *wmep;
int ac;
@@ -1081,12 +1084,11 @@ iwi_wme_setparams(struct iwi_softc *sc, struct ieee80211com *ic)
static void
iwi_update_wme(void *arg, int npending)
{
- struct ieee80211com *ic = arg;
- struct iwi_softc *sc = ic->ic_ifp->if_softc;
+ struct iwi_softc *sc = arg;
IWI_LOCK_DECL;
IWI_LOCK(sc);
- (void) iwi_wme_setparams(sc, ic);
+ (void) iwi_wme_setparams(sc);
IWI_UNLOCK(sc);
}
@@ -2945,7 +2947,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc, struct ieee80211vap *vap)
if ((vap->iv_flags & IEEE80211_F_WME) && ni->ni_ies.wme_ie != NULL) {
/* NB: don't treat WME setup as failure */
- if (iwi_wme_setparams(sc, ic) == 0 && iwi_wme_setie(sc) == 0)
+ if (iwi_wme_setparams(sc) == 0 && iwi_wme_setie(sc) == 0)
assoc->policy |= htole16(IWI_POLICY_WME);
/* XXX complain on failure? */
}
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index ab982044d992..a04d44648692 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -247,7 +247,7 @@ static int iwn_set_link_quality(struct iwn_softc *,
struct ieee80211_node *);
static int iwn_add_broadcast_node(struct iwn_softc *, int);
static int iwn_updateedca(struct ieee80211com *);
-static void iwn_update_mcast(struct ifnet *);
+static void iwn_update_mcast(struct ieee80211com *);
static void iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
static int iwn_set_critical_temp(struct iwn_softc *);
static int iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
@@ -556,6 +556,8 @@ iwn_attach(device_t dev)
ic = ifp->if_l2com;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
@@ -563,7 +565,9 @@ iwn_attach(device_t dev)
ic->ic_caps =
IEEE80211_C_STA /* station mode supported */
| IEEE80211_C_MONITOR /* monitor mode supported */
+#if 0
| IEEE80211_C_BGSCAN /* background scanning */
+#endif
| IEEE80211_C_TXPMGT /* tx power management */
| IEEE80211_C_SHSLOT /* short slot time supported */
| IEEE80211_C_WPA
@@ -1315,10 +1319,10 @@ iwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
+ struct iwn_softc *sc = ic->ic_softc;
struct iwn_vap *ivp;
struct ieee80211vap *vap;
uint8_t mac1[IEEE80211_ADDR_LEN];
- struct iwn_softc *sc = ic->ic_ifp->if_softc;
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
@@ -2525,7 +2529,7 @@ static int
iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
int nchan, struct ieee80211_channel chans[])
{
- struct iwn_softc *sc = ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
int i;
for (i = 0; i < nchan; i++) {
@@ -2534,8 +2538,7 @@ iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
channel = iwn_find_eeprom_channel(sc, c);
if (channel == NULL) {
- if_printf(ic->ic_ifp,
- "%s: invalid channel %u freq %u/0x%x\n",
+ ic_printf(ic, "%s: invalid channel %u freq %u/0x%x\n",
__func__, c->ic_ieee, c->ic_freq, c->ic_flags);
return EINVAL;
}
@@ -2797,7 +2800,7 @@ iwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct iwn_vap *ivp = IWN_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct iwn_softc *sc = ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
int error = 0;
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
@@ -4903,7 +4906,7 @@ iwn_watchdog(void *arg)
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
- if_printf(ifp, "device timeout\n");
+ ic_printf(ic, "device timeout\n");
ieee80211_runtask(ic, &sc->sc_reinit_task);
return;
}
@@ -5247,7 +5250,7 @@ static int
iwn_updateedca(struct ieee80211com *ic)
{
#define IWN_EXP2(x) ((1 << (x)) - 1) /* CWmin = 2^ECWmin - 1 */
- struct iwn_softc *sc = ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
struct iwn_edca_params cmd;
int aci;
@@ -5277,7 +5280,7 @@ iwn_updateedca(struct ieee80211com *ic)
}
static void
-iwn_update_mcast(struct ifnet *ifp)
+iwn_update_mcast(struct ieee80211com *ic)
{
/* Ignore */
}
@@ -7081,7 +7084,7 @@ iwn_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
int baparamset, int batimeout, int baseqctl)
{
#define MS(_v, _f) (((_v) & _f) >> _f##_S)
- struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ni->ni_ic->ic_softc;
struct iwn_ops *ops = &sc->ops;
struct iwn_node *wn = (void *)ni;
struct iwn_node_info node;
@@ -7117,7 +7120,7 @@ static void
iwn_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
{
struct ieee80211com *ic = ni->ni_ic;
- struct iwn_softc *sc = ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
struct iwn_ops *ops = &sc->ops;
struct iwn_node *wn = (void *)ni;
struct iwn_node_info node;
@@ -7145,7 +7148,7 @@ static int
iwn_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int dialogtoken, int baparamset, int batimeout)
{
- struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ni->ni_ic->ic_softc;
int qid;
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -7175,7 +7178,7 @@ static int
iwn_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
int code, int baparamset, int batimeout)
{
- struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ni->ni_ic->ic_softc;
int qid = *(int *)tap->txa_private;
uint8_t tid = tap->txa_tid;
int ret;
@@ -7204,7 +7207,7 @@ iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
uint8_t tid)
{
struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid];
- struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ni->ni_ic->ic_softc;
struct iwn_ops *ops = &sc->ops;
struct iwn_node *wn = (void *)ni;
struct iwn_node_info node;
@@ -7238,7 +7241,7 @@ iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
static void
iwn_ampdu_tx_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
{
- struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
+ struct iwn_softc *sc = ni->ni_ic->ic_softc;
struct iwn_ops *ops = &sc->ops;
uint8_t tid = tap->txa_tid;
int qid;
@@ -8773,8 +8776,8 @@ static void
iwn_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
{
struct ieee80211vap *vap = ss->ss_vap;
- struct iwn_softc *sc = vap->iv_ic->ic_ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
+ struct iwn_softc *sc = ic->ic_softc;
int error;
IWN_LOCK(sc);
diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index b9bba31a5908..77556267fa15 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -54,7 +54,7 @@ int ixgbe_display_debug_stats = 0;
/*********************************************************************
* Driver version
*********************************************************************/
-char ixgbe_driver_version[] = "2.8.3";
+char ixgbe_driver_version[] = "3.1.0";
/*********************************************************************
* PCI Device ID Table
@@ -138,6 +138,7 @@ static int ixgbe_setup_msix(struct adapter *);
static void ixgbe_free_pci_resources(struct adapter *);
static void ixgbe_local_timer(void *);
static int ixgbe_setup_interface(device_t, struct adapter *);
+static void ixgbe_config_gpie(struct adapter *);
static void ixgbe_config_dmac(struct adapter *);
static void ixgbe_config_delay_values(struct adapter *);
static void ixgbe_config_link(struct adapter *);
@@ -204,6 +205,18 @@ static void ixgbe_handle_phy(void *, int);
static void ixgbe_reinit_fdir(void *, int);
#endif
+#ifdef PCI_IOV
+static void ixgbe_ping_all_vfs(struct adapter *);
+static void ixgbe_handle_mbx(void *, int);
+static int ixgbe_init_iov(device_t, u16, const nvlist_t *);
+static void ixgbe_uninit_iov(device_t);
+static int ixgbe_add_vf(device_t, u16, const nvlist_t *);
+static void ixgbe_initialize_iov(struct adapter *);
+static void ixgbe_recalculate_max_frame(struct adapter *);
+static void ixgbe_init_vf(struct adapter *, struct ixgbe_vf *);
+#endif /* PCI_IOV */
+
+
/*********************************************************************
* FreeBSD Device Interface Entry Points
*********************************************************************/
@@ -216,6 +229,11 @@ static device_method_t ix_methods[] = {
DEVMETHOD(device_shutdown, ixgbe_shutdown),
DEVMETHOD(device_suspend, ixgbe_suspend),
DEVMETHOD(device_resume, ixgbe_resume),
+#ifdef PCI_IOV
+ DEVMETHOD(pci_iov_init, ixgbe_init_iov),
+ DEVMETHOD(pci_iov_uninit, ixgbe_uninit_iov),
+ DEVMETHOD(pci_iov_add_vf, ixgbe_add_vf),
+#endif /* PCI_IOV */
DEVMETHOD_END
};
@@ -341,6 +359,8 @@ static int fdir_pballoc = 1;
#include <dev/netmap/ixgbe_netmap.h>
#endif /* DEV_NETMAP */
+static MALLOC_DEFINE(M_IXGBE, "ix", "ix driver allocations");
+
/*********************************************************************
* Device identification routine
*
@@ -472,7 +492,7 @@ ixgbe_attach(device_t dev)
}
/* Allocate multicast array memory. */
- adapter->mta = malloc(sizeof(u8) * IXGBE_ETH_LENGTH_OF_ADDRESS *
+ adapter->mta = malloc(sizeof(*adapter->mta) *
MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT);
if (adapter->mta == NULL) {
device_printf(dev, "Can not allocate multicast setup array\n");
@@ -558,6 +578,28 @@ ixgbe_attach(device_t dev)
/* Set an initial default flow control value */
adapter->fc = ixgbe_fc_full;
+#ifdef PCI_IOV
+ if ((hw->mac.type != ixgbe_mac_82598EB) && (adapter->msix > 1)) {
+ nvlist_t *pf_schema, *vf_schema;
+
+ hw->mbx.ops.init_params(hw);
+ pf_schema = pci_iov_schema_alloc_node();
+ vf_schema = pci_iov_schema_alloc_node();
+ pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL);
+ pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof",
+ IOV_SCHEMA_HASDEFAULT, TRUE);
+ pci_iov_schema_add_bool(vf_schema, "allow-set-mac",
+ IOV_SCHEMA_HASDEFAULT, FALSE);
+ pci_iov_schema_add_bool(vf_schema, "allow-promisc",
+ IOV_SCHEMA_HASDEFAULT, FALSE);
+ error = pci_iov_attach(dev, pf_schema, vf_schema);
+ if (error != 0) {
+ device_printf(dev,
+ "Error %d setting up SR-IOV\n", error);
+ }
+ }
+#endif /* PCI_IOV */
+
/* Check for certain supported features */
ixgbe_check_wol_support(adapter);
ixgbe_check_eee_support(adapter);
@@ -614,6 +656,13 @@ ixgbe_detach(device_t dev)
return (EBUSY);
}
+#ifdef PCI_IOV
+ if (pci_iov_detach(dev) != 0) {
+ device_printf(dev, "SR-IOV in use; detach first.\n");
+ return (EBUSY);
+ }
+#endif /* PCI_IOV */
+
/* Stop the adapter */
IXGBE_CORE_LOCK(adapter);
ixgbe_setup_low_power_mode(adapter);
@@ -634,6 +683,9 @@ ixgbe_detach(device_t dev)
taskqueue_drain(adapter->tq, &adapter->link_task);
taskqueue_drain(adapter->tq, &adapter->mod_task);
taskqueue_drain(adapter->tq, &adapter->msf_task);
+#ifdef PCI_IOV
+ taskqueue_drain(adapter->tq, &adapter->mbx_task);
+#endif
taskqueue_drain(adapter->tq, &adapter->phy_task);
#ifdef IXGBE_FDIR
taskqueue_drain(adapter->tq, &adapter->fdir_task);
@@ -810,6 +862,9 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
adapter->max_frame_size =
ifp->if_mtu + IXGBE_MTU_HDR;
ixgbe_init_locked(adapter);
+#ifdef PCI_IOV
+ ixgbe_recalculate_max_frame(adapter);
+#endif
IXGBE_CORE_UNLOCK(adapter);
}
break;
@@ -925,22 +980,36 @@ ixgbe_init_locked(struct adapter *adapter)
struct ifnet *ifp = adapter->ifp;
device_t dev = adapter->dev;
struct ixgbe_hw *hw = &adapter->hw;
- u32 k, txdctl, mhadd, gpie;
+ struct tx_ring *txr;
+ struct rx_ring *rxr;
+ u32 txdctl, mhadd;
u32 rxdctl, rxctrl;
+#ifdef PCI_IOV
+ enum ixgbe_iov_mode mode;
+#endif
mtx_assert(&adapter->core_mtx, MA_OWNED);
INIT_DEBUGOUT("ixgbe_init_locked: begin");
+
hw->adapter_stopped = FALSE;
ixgbe_stop_adapter(hw);
callout_stop(&adapter->timer);
+#ifdef PCI_IOV
+ mode = ixgbe_get_iov_mode(adapter);
+ adapter->pool = ixgbe_max_vfs(mode);
+ /* Queue indices may change with IOV mode */
+ for (int i = 0; i < adapter->num_queues; i++) {
+ adapter->rx_rings[i].me = ixgbe_pf_que_index(mode, i);
+ adapter->tx_rings[i].me = ixgbe_pf_que_index(mode, i);
+ }
+#endif
/* reprogram the RAR[0] in case user changed it. */
- ixgbe_set_rar(hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
+ ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, IXGBE_RAH_AV);
/* Get the latest mac address, User can use a LAA */
- bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr,
- IXGBE_ETH_LENGTH_OF_ADDRESS);
- ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1);
+ bcopy(IF_LLADDR(ifp), hw->mac.addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
+ ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, 1);
hw->addr_ctrl.rar_used_count = 1;
/* Set the various hardware offload abilities */
@@ -963,6 +1032,9 @@ ixgbe_init_locked(struct adapter *adapter)
}
ixgbe_init_hw(hw);
+#ifdef PCI_IOV
+ ixgbe_initialize_iov(adapter);
+#endif
ixgbe_initialize_transmit_units(adapter);
/* Setup Multicast table */
@@ -972,14 +1044,10 @@ ixgbe_init_locked(struct adapter *adapter)
** Determine the correct mbuf pool
** for doing jumbo frames
*/
- if (adapter->max_frame_size <= 2048)
+ if (adapter->max_frame_size <= MCLBYTES)
adapter->rx_mbuf_sz = MCLBYTES;
- else if (adapter->max_frame_size <= 4096)
- adapter->rx_mbuf_sz = MJUMPAGESIZE;
- else if (adapter->max_frame_size <= 9216)
- adapter->rx_mbuf_sz = MJUM9BYTES;
else
- adapter->rx_mbuf_sz = MJUM16BYTES;
+ adapter->rx_mbuf_sz = MJUMPAGESIZE;
/* Prepare receive descriptors and buffers */
if (ixgbe_setup_receive_structures(adapter)) {
@@ -991,31 +1059,8 @@ ixgbe_init_locked(struct adapter *adapter)
/* Configure RX settings */
ixgbe_initialize_receive_units(adapter);
- gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE);
-
- /* Enable Fan Failure Interrupt */
- gpie |= IXGBE_SDP1_GPIEN_BY_MAC(hw);
-
- /* Add for Module detection */
- if (hw->mac.type == ixgbe_mac_82599EB)
- gpie |= IXGBE_SDP2_GPIEN;
-
- /*
- * Thermal Failure Detection (X540)
- * Link Detection (X552)
- */
- if (hw->mac.type == ixgbe_mac_X540 ||
- hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP ||
- hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T)
- gpie |= IXGBE_SDP0_GPIEN_X540;
-
- if (adapter->msix > 1) {
- /* Enable Enhanced MSIX mode */
- gpie |= IXGBE_GPIE_MSIX_MODE;
- gpie |= IXGBE_GPIE_EIAME | IXGBE_GPIE_PBA_SUPPORT |
- IXGBE_GPIE_OCD;
- }
- IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+ /* Enable SDP & MSIX interrupts based on adapter */
+ ixgbe_config_gpie(adapter);
/* Set MTU size */
if (ifp->if_mtu > ETHERMTU) {
@@ -1028,7 +1073,8 @@ ixgbe_init_locked(struct adapter *adapter)
/* Now enable all the queues */
for (int i = 0; i < adapter->num_queues; i++) {
- txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
+ txr = &adapter->tx_rings[i];
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(txr->me));
txdctl |= IXGBE_TXDCTL_ENABLE;
/* Set WTHRESH to 8, burst writeback */
txdctl |= (8 << 16);
@@ -1040,11 +1086,12 @@ ixgbe_init_locked(struct adapter *adapter)
* Prefetching enables tx line rate even with 1 queue.
*/
txdctl |= (32 << 0) | (1 << 8);
- IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(i), txdctl);
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(txr->me), txdctl);
}
- for (int i = 0; i < adapter->num_queues; i++) {
- rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+ for (int i = 0, j = 0; i < adapter->num_queues; i++) {
+ rxr = &adapter->rx_rings[i];
+ rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me));
if (hw->mac.type == ixgbe_mac_82598EB) {
/*
** PTHRESH = 21
@@ -1055,9 +1102,9 @@ ixgbe_init_locked(struct adapter *adapter)
rxdctl |= 0x080420;
}
rxdctl |= IXGBE_RXDCTL_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), rxdctl);
- for (k = 0; k < 10; k++) {
- if (IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)) &
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), rxdctl);
+ for (; j < 10; j++) {
+ if (IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me)) &
IXGBE_RXDCTL_ENABLE)
break;
else
@@ -1086,10 +1133,10 @@ ixgbe_init_locked(struct adapter *adapter)
struct netmap_kring *kring = &na->rx_rings[i];
int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring);
- IXGBE_WRITE_REG(hw, IXGBE_RDT(i), t);
+ IXGBE_WRITE_REG(hw, IXGBE_RDT(rxr->me), t);
} else
#endif /* DEV_NETMAP */
- IXGBE_WRITE_REG(hw, IXGBE_RDT(i), adapter->num_rx_desc - 1);
+ IXGBE_WRITE_REG(hw, IXGBE_RDT(rxr->me), adapter->num_rx_desc - 1);
}
/* Enable Receive engine */
@@ -1128,9 +1175,9 @@ ixgbe_init_locked(struct adapter *adapter)
#endif
/*
- ** Check on any SFP devices that
- ** need to be kick-started
- */
+ * Check on any SFP devices that
+ * need to be kick-started
+ */
if (hw->phy.type == ixgbe_phy_none) {
int err = hw->phy.ops.identify(hw);
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
@@ -1144,8 +1191,7 @@ ixgbe_init_locked(struct adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_EITR(adapter->vector), IXGBE_LINK_ITR);
/* Configure Energy Efficient Ethernet for supported devices */
- if (adapter->eee_support)
- ixgbe_setup_eee(hw, adapter->eee_enabled);
+ ixgbe_setup_eee(hw, adapter->eee_enabled);
/* Config/Enable Link */
ixgbe_config_link(adapter);
@@ -1165,6 +1211,15 @@ ixgbe_init_locked(struct adapter *adapter)
/* And now turn on interrupts */
ixgbe_enable_intr(adapter);
+#ifdef PCI_IOV
+ /* Enable the use of the MBX by the VF's */
+ {
+ u32 reg = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
+ reg |= IXGBE_CTRL_EXT_PFRSTD;
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, reg);
+ }
+#endif
+
/* Now inform the stack we're ready */
ifp->if_drv_flags |= IFF_DRV_RUNNING;
@@ -1183,6 +1238,51 @@ ixgbe_init(void *arg)
}
static void
+ixgbe_config_gpie(struct adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 gpie;
+
+ gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+
+ /* Fan Failure Interrupt */
+ if (hw->device_id == IXGBE_DEV_ID_82598AT)
+ gpie |= IXGBE_SDP1_GPIEN;
+
+ /*
+ * Module detection (SDP2)
+ * Media ready (SDP1)
+ */
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ gpie |= IXGBE_SDP2_GPIEN;
+ if (hw->device_id != IXGBE_DEV_ID_82599_QSFP_SF_QP)
+ gpie |= IXGBE_SDP1_GPIEN;
+ }
+
+ /*
+ * Thermal Failure Detection (X540)
+ * Link Detection (X557)
+ */
+ if (hw->mac.type == ixgbe_mac_X540 ||
+ hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP ||
+ hw->device_id == IXGBE_DEV_ID_X550EM_X_10G_T)
+ gpie |= IXGBE_SDP0_GPIEN_X540;
+
+ if (adapter->msix > 1) {
+ /* Enable Enhanced MSIX mode */
+ gpie |= IXGBE_GPIE_MSIX_MODE;
+ gpie |= IXGBE_GPIE_EIAME | IXGBE_GPIE_PBA_SUPPORT |
+ IXGBE_GPIE_OCD;
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+ return;
+}
+
+/*
+ * Requires adapter->max_frame_size to be set.
+ */
+static void
ixgbe_config_delay_values(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -1276,10 +1376,9 @@ ixgbe_handle_que(void *context, int pending)
struct adapter *adapter = que->adapter;
struct tx_ring *txr = que->txr;
struct ifnet *ifp = adapter->ifp;
- bool more;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- more = ixgbe_rxeof(que);
+ ixgbe_rxeof(que);
IXGBE_TX_LOCK(txr);
ixgbe_txeof(txr);
#ifndef IXGBE_LEGACY_TX
@@ -1341,8 +1440,8 @@ ixgbe_legacy_irq(void *arg)
IXGBE_TX_UNLOCK(txr);
/* Check for fan failure */
- if ((hw->phy.media_type == ixgbe_media_type_copper) &&
- (reg_eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) {
+ if ((hw->device_id == IXGBE_DEV_ID_82598AT) &&
+ (reg_eicr & IXGBE_EICR_GPI_SDP1)) {
device_printf(adapter->dev, "\nCRITICAL: FAN FAILURE!! "
"REPLACE IMMEDIATELY!!\n");
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
@@ -1381,6 +1480,7 @@ ixgbe_msix_que(void *arg)
bool more;
u32 newitr = 0;
+
/* Protect against spurious interrupts */
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
@@ -1504,6 +1604,10 @@ ixgbe_msix_link(void *arg)
device_printf(adapter->dev, "System shutdown required!\n");
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS);
}
+#ifdef PCI_IOV
+ if (reg_eicr & IXGBE_EICR_MAILBOX)
+ taskqueue_enqueue(adapter->tq, &adapter->mbx_task);
+#endif
}
/* Pluggable optics-related interrupt */
@@ -1569,7 +1673,7 @@ ixgbe_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
}
ifmr->ifm_status |= IFM_ACTIVE;
- layer = ixgbe_get_supported_physical_layer(hw);
+ layer = adapter->phy_layer;
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T ||
layer & IXGBE_PHYSICAL_LAYER_1000BASE_T ||
@@ -1802,18 +1906,17 @@ ixgbe_set_promisc(struct adapter *adapter)
static void
ixgbe_set_multi(struct adapter *adapter)
{
- u32 fctrl;
- u8 *mta;
- u8 *update_ptr;
- struct ifmultiaddr *ifma;
- int mcnt = 0;
- struct ifnet *ifp = adapter->ifp;
+ u32 fctrl;
+ u8 *update_ptr;
+ struct ifmultiaddr *ifma;
+ struct ixgbe_mc_addr *mta;
+ int mcnt = 0;
+ struct ifnet *ifp = adapter->ifp;
IOCTL_DEBUGOUT("ixgbe_set_multi: begin");
mta = adapter->mta;
- bzero(mta, sizeof(u8) * IXGBE_ETH_LENGTH_OF_ADDRESS *
- MAX_NUM_MULTICAST_ADDRESSES);
+ bzero(mta, sizeof(*mta) * MAX_NUM_MULTICAST_ADDRESSES);
#if __FreeBSD_version < 800000
IF_ADDR_LOCK(ifp);
@@ -1826,8 +1929,8 @@ ixgbe_set_multi(struct adapter *adapter)
if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
break;
bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
- &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS],
- IXGBE_ETH_LENGTH_OF_ADDRESS);
+ mta[mcnt].addr, IXGBE_ETH_LENGTH_OF_ADDRESS);
+ mta[mcnt].vmdq = adapter->pool;
mcnt++;
}
#if __FreeBSD_version < 800000
@@ -1850,7 +1953,7 @@ ixgbe_set_multi(struct adapter *adapter)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) {
- update_ptr = mta;
+ update_ptr = (u8 *)mta;
ixgbe_update_mc_addr_list(&adapter->hw,
update_ptr, mcnt, ixgbe_mc_array_itr, TRUE);
}
@@ -1866,13 +1969,13 @@ ixgbe_set_multi(struct adapter *adapter)
static u8 *
ixgbe_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq)
{
- u8 *addr = *update_ptr;
- u8 *newptr;
- *vmdq = 0;
+ struct ixgbe_mc_addr *mta;
- newptr = addr + IXGBE_ETH_LENGTH_OF_ADDRESS;
- *update_ptr = newptr;
- return addr;
+ mta = (struct ixgbe_mc_addr *)*update_ptr;
+ *vmdq = mta->vmdq;
+
+ *update_ptr = (u8*)(mta + 1);;
+ return (mta->addr);
}
@@ -1954,6 +2057,7 @@ watchdog:
ixgbe_init_locked(adapter);
}
+
/*
** Note: this routine updates the OS on the link state
** the real check of the hardware only happens with
@@ -1977,6 +2081,9 @@ ixgbe_update_link_status(struct adapter *adapter)
/* Update DMA coalescing config */
ixgbe_config_dmac(adapter);
if_link_state_change(ifp, LINK_STATE_UP);
+#ifdef PCI_IOV
+ ixgbe_ping_all_vfs(adapter);
+#endif
}
} else { /* Link down */
if (adapter->link_active == TRUE) {
@@ -1984,6 +2091,9 @@ ixgbe_update_link_status(struct adapter *adapter)
device_printf(dev,"Link is Down\n");
if_link_state_change(ifp, LINK_STATE_DOWN);
adapter->link_active = FALSE;
+#ifdef PCI_IOV
+ ixgbe_ping_all_vfs(adapter);
+#endif
}
}
@@ -2083,7 +2193,7 @@ ixgbe_setup_optics(struct adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
int layer;
- layer = ixgbe_get_supported_physical_layer(hw);
+ layer = adapter->phy_layer = ixgbe_get_supported_physical_layer(hw);
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) {
adapter->optics = IFM_10G_T;
@@ -2281,17 +2391,19 @@ ixgbe_allocate_msix(struct adapter *adapter)
#endif
if (adapter->num_queues > 1)
bus_bind_intr(dev, que->res, cpu_id);
-
+#ifdef IXGBE_DEBUG
#ifdef RSS
device_printf(dev,
"Bound RSS bucket %d to CPU %d\n",
i, cpu_id);
#else
- if (bootverbose)
- device_printf(dev,
- "Bound queue %d to cpu %d\n",
- i, cpu_id);
+ device_printf(dev,
+ "Bound queue %d to cpu %d\n",
+ i, cpu_id);
#endif
+#endif /* IXGBE_DEBUG */
+
+
#ifndef IXGBE_LEGACY_TX
TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr);
#endif
@@ -2337,6 +2449,9 @@ ixgbe_allocate_msix(struct adapter *adapter)
TASK_INIT(&adapter->link_task, 0, ixgbe_handle_link, adapter);
TASK_INIT(&adapter->mod_task, 0, ixgbe_handle_mod, adapter);
TASK_INIT(&adapter->msf_task, 0, ixgbe_handle_msf, adapter);
+#ifdef PCI_IOV
+ TASK_INIT(&adapter->mbx_task, 0, ixgbe_handle_mbx, adapter);
+#endif
TASK_INIT(&adapter->phy_task, 0, ixgbe_handle_phy, adapter);
#ifdef IXGBE_FDIR
TASK_INIT(&adapter->fdir_task, 0, ixgbe_reinit_fdir, adapter);
@@ -2630,7 +2745,7 @@ ixgbe_add_media_types(struct adapter *adapter)
device_t dev = adapter->dev;
int layer;
- layer = ixgbe_get_supported_physical_layer(hw);
+ layer = adapter->phy_layer = ixgbe_get_supported_physical_layer(hw);
/* Media types with matching FreeBSD media defines */
if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T)
@@ -2741,19 +2856,20 @@ ixgbe_initialize_transmit_units(struct adapter *adapter)
for (int i = 0; i < adapter->num_queues; i++, txr++) {
u64 tdba = txr->txdma.dma_paddr;
u32 txctrl = 0;
+ int j = txr->me;
- IXGBE_WRITE_REG(hw, IXGBE_TDBAL(i),
+ IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
(tdba & 0x00000000ffffffffULL));
- IXGBE_WRITE_REG(hw, IXGBE_TDBAH(i), (tdba >> 32));
- IXGBE_WRITE_REG(hw, IXGBE_TDLEN(i),
+ IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
+ IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j),
adapter->num_tx_desc * sizeof(union ixgbe_adv_tx_desc));
/* Setup the HW Tx Head and Tail descriptor pointers */
- IXGBE_WRITE_REG(hw, IXGBE_TDH(i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_TDT(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
/* Cache the tail address */
- txr->tail = IXGBE_TDT(txr->me);
+ txr->tail = IXGBE_TDT(j);
/* Set the processing limit */
txr->process_limit = ixgbe_tx_process_limit;
@@ -2761,23 +2877,23 @@ ixgbe_initialize_transmit_units(struct adapter *adapter)
/* Disable Head Writeback */
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
break;
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
default:
- txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
+ txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j));
break;
}
txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN;
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), txctrl);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
break;
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
default:
- IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), txctrl);
+ IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl);
break;
}
@@ -2785,6 +2901,9 @@ ixgbe_initialize_transmit_units(struct adapter *adapter)
if (hw->mac.type != ixgbe_mac_82598EB) {
u32 dmatxctl, rttdcs;
+#ifdef PCI_IOV
+ enum ixgbe_iov_mode mode = ixgbe_get_iov_mode(adapter);
+#endif
dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
dmatxctl |= IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
@@ -2792,7 +2911,11 @@ ixgbe_initialize_transmit_units(struct adapter *adapter)
rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
rttdcs |= IXGBE_RTTDCS_ARBDIS;
IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
+#ifdef PCI_IOV
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, ixgbe_get_mtqc(mode));
+#else
IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB);
+#endif
rttdcs &= ~IXGBE_RTTDCS_ARBDIS;
IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs);
}
@@ -2804,17 +2927,14 @@ static void
ixgbe_initialise_rss_mapping(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- uint32_t reta;
- int i, j, queue_id, table_size;
- int index_mult;
- uint32_t rss_key[10];
- uint32_t mrqc;
+ u32 reta = 0, mrqc, rss_key[10];
+ int queue_id, table_size, index_mult;
#ifdef RSS
- uint32_t rss_hash_config;
+ u32 rss_hash_config;
+#endif
+#ifdef PCI_IOV
+ enum ixgbe_iov_mode mode;
#endif
-
- /* Setup RSS */
- reta = 0;
#ifdef RSS
/* Fetch the configured RSS key */
@@ -2840,7 +2960,7 @@ ixgbe_initialise_rss_mapping(struct adapter *adapter)
}
/* Set up the redirection table */
- for (i = 0, j = 0; i < table_size; i++, j++) {
+ for (int i = 0, j = 0; i < table_size; i++, j++) {
if (j == adapter->num_queues) j = 0;
#ifdef RSS
/*
@@ -2907,19 +3027,16 @@ ixgbe_initialise_rss_mapping(struct adapter *adapter)
mrqc = IXGBE_MRQC_RSSEN
| IXGBE_MRQC_RSS_FIELD_IPV4
| IXGBE_MRQC_RSS_FIELD_IPV4_TCP
-#if 0
- | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
-#endif
| IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP
| IXGBE_MRQC_RSS_FIELD_IPV6_EX
| IXGBE_MRQC_RSS_FIELD_IPV6
| IXGBE_MRQC_RSS_FIELD_IPV6_TCP
-#if 0
- | IXGBE_MRQC_RSS_FIELD_IPV6_UDP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP
-#endif
;
#endif /* RSS */
+#ifdef PCI_IOV
+ mode = ixgbe_get_iov_mode(adapter);
+ mrqc |= ixgbe_get_mrqc(mode);
+#endif
IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
}
@@ -2978,16 +3095,17 @@ ixgbe_initialize_receive_units(struct adapter *adapter)
for (int i = 0; i < adapter->num_queues; i++, rxr++) {
u64 rdba = rxr->rxdma.dma_paddr;
+ int j = rxr->me;
/* Setup the Base and Length of the Rx Descriptor Ring */
- IXGBE_WRITE_REG(hw, IXGBE_RDBAL(i),
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j),
(rdba & 0x00000000ffffffffULL));
- IXGBE_WRITE_REG(hw, IXGBE_RDBAH(i), (rdba >> 32));
- IXGBE_WRITE_REG(hw, IXGBE_RDLEN(i),
+ IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32));
+ IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j),
adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc));
/* Set up the SRRCTL register */
- srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(i));
+ srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(j));
srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
srrctl |= bufsz;
@@ -3006,11 +3124,11 @@ ixgbe_initialize_receive_units(struct adapter *adapter)
srrctl &= ~IXGBE_SRRCTL_DROP_EN;
}
- IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(i), srrctl);
+ IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(j), srrctl);
/* Setup the HW Rx Head and Tail Descriptor Pointers */
- IXGBE_WRITE_REG(hw, IXGBE_RDH(i), 0);
- IXGBE_WRITE_REG(hw, IXGBE_RDT(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0);
/* Set the processing limit */
rxr->process_limit = ixgbe_rx_process_limit;
@@ -3126,9 +3244,9 @@ ixgbe_setup_vlan_hw_support(struct adapter *adapter)
rxr = &adapter->rx_rings[i];
/* On 82599 the VLAN enable is per/queue in RXDCTL */
if (hw->mac.type != ixgbe_mac_82598EB) {
- ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+ ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxr->me));
ctrl |= IXGBE_RXDCTL_VME;
- IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), ctrl);
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxr->me), ctrl);
}
rxr->vtag_strip = TRUE;
}
@@ -3178,6 +3296,9 @@ ixgbe_enable_intr(struct adapter *adapter)
#ifdef IXGBE_FDIR
mask |= IXGBE_EIMS_FLOW_DIR;
#endif
+#ifdef PCI_IOV
+ mask |= IXGBE_EIMS_MAILBOX;
+#endif
break;
case ixgbe_mac_X540:
/* Detect if Thermal Sensor is enabled */
@@ -3201,6 +3322,9 @@ ixgbe_enable_intr(struct adapter *adapter)
#ifdef IXGBE_FDIR
mask |= IXGBE_EIMS_FLOW_DIR;
#endif
+#ifdef PCI_IOV
+ mask |= IXGBE_EIMS_MAILBOX;
+#endif
/* falls through */
default:
break;
@@ -3214,6 +3338,9 @@ ixgbe_enable_intr(struct adapter *adapter)
/* Don't autoclear Link */
mask &= ~IXGBE_EIMS_OTHER;
mask &= ~IXGBE_EIMS_LSC;
+#ifdef PCI_IOV
+ mask &= ~IXGBE_EIMS_MAILBOX;
+#endif
IXGBE_WRITE_REG(hw, IXGBE_EIAC, mask);
}
@@ -3412,8 +3539,8 @@ ixgbe_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type)
static void
ixgbe_configure_ivars(struct adapter *adapter)
{
- struct ix_queue *que = adapter->queues;
- u32 newitr;
+ struct ix_queue *que = adapter->queues;
+ u32 newitr;
if (ixgbe_max_interrupt_rate > 0)
newitr = (4000000 / ixgbe_max_interrupt_rate) & 0x0FF8;
@@ -3427,10 +3554,12 @@ ixgbe_configure_ivars(struct adapter *adapter)
}
for (int i = 0; i < adapter->num_queues; i++, que++) {
+ struct rx_ring *rxr = &adapter->rx_rings[i];
+ struct tx_ring *txr = &adapter->tx_rings[i];
/* First the RX queue entry */
- ixgbe_set_ivar(adapter, i, que->msix, 0);
+ ixgbe_set_ivar(adapter, rxr->me, que->msix, 0);
/* ... and the TX */
- ixgbe_set_ivar(adapter, i, que->msix, 1);
+ ixgbe_set_ivar(adapter, txr->me, que->msix, 1);
/* Set an Initial EITR value */
IXGBE_WRITE_REG(&adapter->hw,
IXGBE_EITR(que->msix), newitr);
@@ -3444,7 +3573,8 @@ ixgbe_configure_ivars(struct adapter *adapter)
** ixgbe_sfp_probe - called in the local timer to
** determine if a port had optics inserted.
*/
-static bool ixgbe_sfp_probe(struct adapter *adapter)
+static bool
+ixgbe_sfp_probe(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
device_t dev = adapter->dev;
@@ -3504,6 +3634,7 @@ ixgbe_handle_mod(void *context, int pending)
"Unsupported SFP+ module type was detected.\n");
return;
}
+
err = hw->mac.ops.setup_sfp(hw);
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
device_printf(dev,
@@ -3626,9 +3757,7 @@ ixgbe_check_eee_support(struct adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- adapter->eee_support = adapter->eee_enabled =
- (hw->device_id == IXGBE_DEV_ID_X550T ||
- hw->device_id == IXGBE_DEV_ID_X550EM_X_KR);
+ adapter->eee_enabled = !!(hw->mac.ops.setup_eee);
}
/*
@@ -4004,8 +4133,7 @@ ixgbe_add_device_sysctls(struct adapter *adapter)
ixgbe_sysctl_dmac, "I", "DMA Coalesce");
/* for X550T and X550EM backplane devices */
- if (hw->device_id == IXGBE_DEV_ID_X550T ||
- hw->device_id == IXGBE_DEV_ID_X550EM_X_KR) {
+ if (hw->mac.ops.setup_eee) {
struct sysctl_oid *eee_node;
struct sysctl_oid_list *eee_list;
@@ -4625,6 +4753,7 @@ static int
ixgbe_sysctl_eee_enable(SYSCTL_HANDLER_ARGS)
{
struct adapter *adapter = (struct adapter *) arg1;
+ struct ixgbe_hw *hw = &adapter->hw;
struct ifnet *ifp = adapter->ifp;
int new_eee_enabled, error = 0;
@@ -4635,7 +4764,7 @@ ixgbe_sysctl_eee_enable(SYSCTL_HANDLER_ARGS)
if (new_eee_enabled == adapter->eee_enabled)
return (0);
- if (new_eee_enabled > 0 && !adapter->eee_support)
+ if (new_eee_enabled > 0 && !hw->mac.ops.setup_eee)
return (ENODEV);
else
adapter->eee_enabled = !!(new_eee_enabled);
@@ -4751,10 +4880,19 @@ ixgbe_enable_rx_drop(struct adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
for (int i = 0; i < adapter->num_queues; i++) {
- u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(i));
+ struct rx_ring *rxr = &adapter->rx_rings[i];
+ u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(rxr->me));
srrctl |= IXGBE_SRRCTL_DROP_EN;
- IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(i), srrctl);
+ IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl);
}
+#ifdef PCI_IOV
+ /* enable drop for each vf */
+ for (int i = 0; i < adapter->num_vfs; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_QDE,
+ (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT) |
+ IXGBE_QDE_ENABLE));
+ }
+#endif
}
static void
@@ -4763,10 +4901,18 @@ ixgbe_disable_rx_drop(struct adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw;
for (int i = 0; i < adapter->num_queues; i++) {
- u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(i));
+ struct rx_ring *rxr = &adapter->rx_rings[i];
+ u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(rxr->me));
srrctl &= ~IXGBE_SRRCTL_DROP_EN;
- IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(i), srrctl);
+ IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl);
}
+#ifdef PCI_IOV
+ /* disable drop for each vf */
+ for (int i = 0; i < adapter->num_vfs; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_QDE,
+ (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT)));
+ }
+#endif
}
static void
@@ -4793,4 +4939,722 @@ ixgbe_rearm_queues(struct adapter *adapter, u64 queues)
}
}
+#ifdef PCI_IOV
+
+/*
+** Support functions for SRIOV/VF management
+*/
+
+static void
+ixgbe_ping_all_vfs(struct adapter *adapter)
+{
+ struct ixgbe_vf *vf;
+
+ for (int i = 0; i < adapter->num_vfs; i++) {
+ vf = &adapter->vfs[i];
+ if (vf->flags & IXGBE_VF_ACTIVE)
+ ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG);
+ }
+}
+
+
+static void
+ixgbe_vf_set_default_vlan(struct adapter *adapter, struct ixgbe_vf *vf,
+ uint16_t tag)
+{
+ struct ixgbe_hw *hw;
+ uint32_t vmolr, vmvir;
+
+ hw = &adapter->hw;
+
+ vf->vlan_tag = tag;
+
+ vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf->pool));
+
+ /* Do not receive packets that pass inexact filters. */
+ vmolr &= ~(IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_ROPE);
+
+ /* Disable Multicast Promicuous Mode. */
+ vmolr &= ~IXGBE_VMOLR_MPE;
+
+ /* Accept broadcasts. */
+ vmolr |= IXGBE_VMOLR_BAM;
+
+ if (tag == 0) {
+ /* Accept non-vlan tagged traffic. */
+ //vmolr |= IXGBE_VMOLR_AUPE;
+
+ /* Allow VM to tag outgoing traffic; no default tag. */
+ vmvir = 0;
+ } else {
+ /* Require vlan-tagged traffic. */
+ vmolr &= ~IXGBE_VMOLR_AUPE;
+
+ /* Tag all traffic with provided vlan tag. */
+ vmvir = (tag | IXGBE_VMVIR_VLANA_DEFAULT);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf->pool), vmolr);
+ IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf->pool), vmvir);
+}
+
+
+static boolean_t
+ixgbe_vf_frame_size_compatible(struct adapter *adapter, struct ixgbe_vf *vf)
+{
+
+ /*
+ * Frame size compatibility between PF and VF is only a problem on
+ * 82599-based cards. X540 and later support any combination of jumbo
+ * frames on PFs and VFs.
+ */
+ if (adapter->hw.mac.type != ixgbe_mac_82599EB)
+ return (TRUE);
+
+ switch (vf->api_ver) {
+ case IXGBE_API_VER_1_0:
+ case IXGBE_API_VER_UNKNOWN:
+ /*
+ * On legacy (1.0 and older) VF versions, we don't support jumbo
+ * frames on either the PF or the VF.
+ */
+ if (adapter->max_frame_size > ETHER_MAX_LEN ||
+ vf->max_frame_size > ETHER_MAX_LEN)
+ return (FALSE);
+
+ return (TRUE);
+
+ break;
+ case IXGBE_API_VER_1_1:
+ default:
+ /*
+ * 1.1 or later VF versions always work if they aren't using
+ * jumbo frames.
+ */
+ if (vf->max_frame_size <= ETHER_MAX_LEN)
+ return (TRUE);
+
+ /*
+ * Jumbo frames only work with VFs if the PF is also using jumbo
+ * frames.
+ */
+ if (adapter->max_frame_size <= ETHER_MAX_LEN)
+ return (TRUE);
+
+ return (FALSE);
+
+ }
+}
+
+
+static void
+ixgbe_process_vf_reset(struct adapter *adapter, struct ixgbe_vf *vf)
+{
+ ixgbe_vf_set_default_vlan(adapter, vf, vf->default_vlan);
+
+ // XXX clear multicast addresses
+
+ ixgbe_clear_rar(&adapter->hw, vf->rar_index);
+
+ vf->api_ver = IXGBE_API_VER_UNKNOWN;
+}
+
+
+static void
+ixgbe_vf_enable_transmit(struct adapter *adapter, struct ixgbe_vf *vf)
+{
+ struct ixgbe_hw *hw;
+ uint32_t vf_index, vfte;
+
+ hw = &adapter->hw;
+
+ vf_index = IXGBE_VF_INDEX(vf->pool);
+ vfte = IXGBE_READ_REG(hw, IXGBE_VFTE(vf_index));
+ vfte |= IXGBE_VF_BIT(vf->pool);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_index), vfte);
+}
+
+
+static void
+ixgbe_vf_enable_receive(struct adapter *adapter, struct ixgbe_vf *vf)
+{
+ struct ixgbe_hw *hw;
+ uint32_t vf_index, vfre;
+
+ hw = &adapter->hw;
+
+ vf_index = IXGBE_VF_INDEX(vf->pool);
+ vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(vf_index));
+ if (ixgbe_vf_frame_size_compatible(adapter, vf))
+ vfre |= IXGBE_VF_BIT(vf->pool);
+ else
+ vfre &= ~IXGBE_VF_BIT(vf->pool);
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_index), vfre);
+}
+
+
+static void
+ixgbe_vf_reset_msg(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
+{
+ struct ixgbe_hw *hw;
+ uint32_t ack;
+ uint32_t resp[IXGBE_VF_PERMADDR_MSG_LEN];
+
+ hw = &adapter->hw;
+
+ ixgbe_process_vf_reset(adapter, vf);
+
+ if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) {
+ ixgbe_set_rar(&adapter->hw, vf->rar_index,
+ vf->ether_addr, vf->pool, TRUE);
+ ack = IXGBE_VT_MSGTYPE_ACK;
+ } else
+ ack = IXGBE_VT_MSGTYPE_NACK;
+
+ ixgbe_vf_enable_transmit(adapter, vf);
+ ixgbe_vf_enable_receive(adapter, vf);
+
+ vf->flags |= IXGBE_VF_CTS;
+
+ resp[0] = IXGBE_VF_RESET | ack | IXGBE_VT_MSGTYPE_CTS;
+ bcopy(vf->ether_addr, &resp[1], ETHER_ADDR_LEN);
+ resp[3] = hw->mac.mc_filter_type;
+ ixgbe_write_mbx(hw, resp, IXGBE_VF_PERMADDR_MSG_LEN, vf->pool);
+}
+
+
+static void
+ixgbe_vf_set_mac(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
+{
+ uint8_t *mac;
+
+ mac = (uint8_t*)&msg[1];
+
+ /* Check that the VF has permission to change the MAC address. */
+ if (!(vf->flags & IXGBE_VF_CAP_MAC) && ixgbe_vf_mac_changed(vf, mac)) {
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+ return;
+ }
+
+ if (ixgbe_validate_mac_addr(mac) != 0) {
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+ return;
+ }
+
+ bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN);
+
+ ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr,
+ vf->pool, TRUE);
+
+ ixgbe_send_vf_ack(adapter, vf, msg[0]);
+}
+
+
+/*
+** VF multicast addresses are set by using the appropriate bit in
+** 1 of 128 32 bit addresses (4096 possible).
+*/
+static void
+ixgbe_vf_set_mc_addr(struct adapter *adapter, struct ixgbe_vf *vf, u32 *msg)
+{
+ u16 *list = (u16*)&msg[1];
+ int entries;
+ u32 vmolr, vec_bit, vec_reg, mta_reg;
+
+ entries = (msg[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
+ entries = min(entries, IXGBE_MAX_VF_MC);
+
+ vmolr = IXGBE_READ_REG(&adapter->hw, IXGBE_VMOLR(vf->pool));
+
+ vf->num_mc_hashes = entries;
+
+ /* Set the appropriate MTA bit */
+ for (int i = 0; i < entries; i++) {
+ vf->mc_hash[i] = list[i];
+ vec_reg = (vf->mc_hash[i] >> 5) & 0x7F;
+ vec_bit = vf->mc_hash[i] & 0x1F;
+ mta_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_MTA(vec_reg));
+ mta_reg |= (1 << vec_bit);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_MTA(vec_reg), mta_reg);
+ }
+
+ vmolr |= IXGBE_VMOLR_ROMPE;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_VMOLR(vf->pool), vmolr);
+ ixgbe_send_vf_ack(adapter, vf, msg[0]);
+ return;
+}
+
+
+static void
+ixgbe_vf_set_vlan(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
+{
+ struct ixgbe_hw *hw;
+ int enable;
+ uint16_t tag;
+
+ hw = &adapter->hw;
+ enable = IXGBE_VT_MSGINFO(msg[0]);
+ tag = msg[1] & IXGBE_VLVF_VLANID_MASK;
+
+ if (!(vf->flags & IXGBE_VF_CAP_VLAN)) {
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+ return;
+ }
+
+ /* It is illegal to enable vlan tag 0. */
+ if (tag == 0 && enable != 0){
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+ return;
+ }
+
+ ixgbe_set_vfta(hw, tag, vf->pool, enable);
+ ixgbe_send_vf_ack(adapter, vf, msg[0]);
+}
+
+
+static void
+ixgbe_vf_set_lpe(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
+{
+ struct ixgbe_hw *hw;
+ uint32_t vf_max_size, pf_max_size, mhadd;
+
+ hw = &adapter->hw;
+ vf_max_size = msg[1];
+
+ if (vf_max_size < ETHER_CRC_LEN) {
+ /* We intentionally ACK invalid LPE requests. */
+ ixgbe_send_vf_ack(adapter, vf, msg[0]);
+ return;
+ }
+
+ vf_max_size -= ETHER_CRC_LEN;
+
+ if (vf_max_size > IXGBE_MAX_FRAME_SIZE) {
+ /* We intentionally ACK invalid LPE requests. */
+ ixgbe_send_vf_ack(adapter, vf, msg[0]);
+ return;
+ }
+
+ vf->max_frame_size = vf_max_size;
+ ixgbe_update_max_frame(adapter, vf->max_frame_size);
+
+ /*
+ * We might have to disable reception to this VF if the frame size is
+ * not compatible with the config on the PF.
+ */
+ ixgbe_vf_enable_receive(adapter, vf);
+
+ mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
+ pf_max_size = (mhadd & IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT;
+
+ if (pf_max_size < adapter->max_frame_size) {
+ mhadd &= ~IXGBE_MHADD_MFS_MASK;
+ mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT;
+ IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
+ }
+
+ ixgbe_send_vf_ack(adapter, vf, msg[0]);
+}
+
+
+static void
+ixgbe_vf_set_macvlan(struct adapter *adapter, struct ixgbe_vf *vf,
+ uint32_t *msg)
+{
+ //XXX implement this
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+}
+
+
+static void
+ixgbe_vf_api_negotiate(struct adapter *adapter, struct ixgbe_vf *vf,
+ uint32_t *msg)
+{
+
+ switch (msg[0]) {
+ case IXGBE_API_VER_1_0:
+ case IXGBE_API_VER_1_1:
+ vf->api_ver = msg[0];
+ ixgbe_send_vf_ack(adapter, vf, msg[0]);
+ break;
+ default:
+ vf->api_ver = IXGBE_API_VER_UNKNOWN;
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+ break;
+ }
+}
+
+
+static void
+ixgbe_vf_get_queues(struct adapter *adapter, struct ixgbe_vf *vf,
+ uint32_t *msg)
+{
+ struct ixgbe_hw *hw;
+ uint32_t resp[IXGBE_VF_GET_QUEUES_RESP_LEN];
+ int num_queues;
+
+ hw = &adapter->hw;
+
+ /* GET_QUEUES is not supported on pre-1.1 APIs. */
+ switch (msg[0]) {
+ case IXGBE_API_VER_1_0:
+ case IXGBE_API_VER_UNKNOWN:
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+ return;
+ }
+
+ resp[0] = IXGBE_VF_GET_QUEUES | IXGBE_VT_MSGTYPE_ACK |
+ IXGBE_VT_MSGTYPE_CTS;
+
+ num_queues = ixgbe_vf_queues(ixgbe_get_iov_mode(adapter));
+ resp[IXGBE_VF_TX_QUEUES] = num_queues;
+ resp[IXGBE_VF_RX_QUEUES] = num_queues;
+ resp[IXGBE_VF_TRANS_VLAN] = (vf->default_vlan != 0);
+ resp[IXGBE_VF_DEF_QUEUE] = 0;
+
+ ixgbe_write_mbx(hw, resp, IXGBE_VF_GET_QUEUES_RESP_LEN, vf->pool);
+}
+
+
+static void
+ixgbe_process_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf)
+{
+ struct ixgbe_hw *hw;
+ uint32_t msg[IXGBE_VFMAILBOX_SIZE];
+ int error;
+
+ hw = &adapter->hw;
+
+ error = ixgbe_read_mbx(hw, msg, IXGBE_VFMAILBOX_SIZE, vf->pool);
+
+ if (error != 0)
+ return;
+
+ CTR3(KTR_MALLOC, "%s: received msg %x from %d",
+ adapter->ifp->if_xname, msg[0], vf->pool);
+ if (msg[0] == IXGBE_VF_RESET) {
+ ixgbe_vf_reset_msg(adapter, vf, msg);
+ return;
+ }
+
+ if (!(vf->flags & IXGBE_VF_CTS)) {
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+ return;
+ }
+
+ switch (msg[0] & IXGBE_VT_MSG_MASK) {
+ case IXGBE_VF_SET_MAC_ADDR:
+ ixgbe_vf_set_mac(adapter, vf, msg);
+ break;
+ case IXGBE_VF_SET_MULTICAST:
+ ixgbe_vf_set_mc_addr(adapter, vf, msg);
+ break;
+ case IXGBE_VF_SET_VLAN:
+ ixgbe_vf_set_vlan(adapter, vf, msg);
+ break;
+ case IXGBE_VF_SET_LPE:
+ ixgbe_vf_set_lpe(adapter, vf, msg);
+ break;
+ case IXGBE_VF_SET_MACVLAN:
+ ixgbe_vf_set_macvlan(adapter, vf, msg);
+ break;
+ case IXGBE_VF_API_NEGOTIATE:
+ ixgbe_vf_api_negotiate(adapter, vf, msg);
+ break;
+ case IXGBE_VF_GET_QUEUES:
+ ixgbe_vf_get_queues(adapter, vf, msg);
+ break;
+ default:
+ ixgbe_send_vf_nack(adapter, vf, msg[0]);
+ }
+}
+
+
+/*
+ * Tasklet for handling VF -> PF mailbox messages.
+ */
+static void
+ixgbe_handle_mbx(void *context, int pending)
+{
+ struct adapter *adapter;
+ struct ixgbe_hw *hw;
+ struct ixgbe_vf *vf;
+ int i;
+
+ adapter = context;
+ hw = &adapter->hw;
+
+ IXGBE_CORE_LOCK(adapter);
+ for (i = 0; i < adapter->num_vfs; i++) {
+ vf = &adapter->vfs[i];
+
+ if (vf->flags & IXGBE_VF_ACTIVE) {
+ if (ixgbe_check_for_rst(hw, vf->pool) == 0)
+ ixgbe_process_vf_reset(adapter, vf);
+
+ if (ixgbe_check_for_msg(hw, vf->pool) == 0)
+ ixgbe_process_vf_msg(adapter, vf);
+
+ if (ixgbe_check_for_ack(hw, vf->pool) == 0)
+ ixgbe_process_vf_ack(adapter, vf);
+ }
+ }
+ IXGBE_CORE_UNLOCK(adapter);
+}
+
+
+static int
+ixgbe_init_iov(device_t dev, u16 num_vfs, const nvlist_t *config)
+{
+ struct adapter *adapter;
+ enum ixgbe_iov_mode mode;
+
+ adapter = device_get_softc(dev);
+ adapter->num_vfs = num_vfs;
+ mode = ixgbe_get_iov_mode(adapter);
+
+ if (num_vfs > ixgbe_max_vfs(mode)) {
+ adapter->num_vfs = 0;
+ return (ENOSPC);
+ }
+
+ IXGBE_CORE_LOCK(adapter);
+
+ adapter->vfs = malloc(sizeof(*adapter->vfs) * num_vfs, M_IXGBE,
+ M_NOWAIT | M_ZERO);
+
+ if (adapter->vfs == NULL) {
+ adapter->num_vfs = 0;
+ IXGBE_CORE_UNLOCK(adapter);
+ return (ENOMEM);
+ }
+
+ ixgbe_init_locked(adapter);
+
+ IXGBE_CORE_UNLOCK(adapter);
+
+ return (0);
+}
+
+
+static void
+ixgbe_uninit_iov(device_t dev)
+{
+ struct ixgbe_hw *hw;
+ struct adapter *adapter;
+ uint32_t pf_reg, vf_reg;
+
+ adapter = device_get_softc(dev);
+ hw = &adapter->hw;
+
+ IXGBE_CORE_LOCK(adapter);
+
+ /* Enable rx/tx for the PF and disable it for all VFs. */
+ pf_reg = IXGBE_VF_INDEX(adapter->pool);
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(pf_reg),
+ IXGBE_VF_BIT(adapter->pool));
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(pf_reg),
+ IXGBE_VF_BIT(adapter->pool));
+
+ if (pf_reg == 0)
+ vf_reg = 1;
+ else
+ vf_reg = 0;
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), 0);
+
+ IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, 0);
+
+ free(adapter->vfs, M_IXGBE);
+ adapter->vfs = NULL;
+ adapter->num_vfs = 0;
+
+ IXGBE_CORE_UNLOCK(adapter);
+}
+
+
+static void
+ixgbe_initialize_iov(struct adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ uint32_t mrqc, mtqc, vt_ctl, vf_reg, gcr_ext, gpie;
+ enum ixgbe_iov_mode mode;
+ int i;
+
+ mode = ixgbe_get_iov_mode(adapter);
+ if (mode == IXGBE_NO_VM)
+ return;
+
+ IXGBE_CORE_LOCK_ASSERT(adapter);
+
+ mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC);
+ mrqc &= ~IXGBE_MRQC_MRQE_MASK;
+
+ switch (mode) {
+ case IXGBE_64_VM:
+ mrqc |= IXGBE_MRQC_VMDQRSS64EN;
+ break;
+ case IXGBE_32_VM:
+ mrqc |= IXGBE_MRQC_VMDQRSS32EN;
+ break;
+ default:
+ panic("Unexpected SR-IOV mode %d", mode);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
+
+ mtqc = IXGBE_MTQC_VT_ENA;
+ switch (mode) {
+ case IXGBE_64_VM:
+ mtqc |= IXGBE_MTQC_64VF;
+ break;
+ case IXGBE_32_VM:
+ mtqc |= IXGBE_MTQC_32VF;
+ break;
+ default:
+ panic("Unexpected SR-IOV mode %d", mode);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, mtqc);
+
+
+ gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
+ gcr_ext |= IXGBE_GCR_EXT_MSIX_EN;
+ gcr_ext &= ~IXGBE_GCR_EXT_VT_MODE_MASK;
+ switch (mode) {
+ case IXGBE_64_VM:
+ gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64;
+ break;
+ case IXGBE_32_VM:
+ gcr_ext |= IXGBE_GCR_EXT_VT_MODE_32;
+ break;
+ default:
+ panic("Unexpected SR-IOV mode %d", mode);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
+
+
+ gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+ gcr_ext &= ~IXGBE_GPIE_VTMODE_MASK;
+ switch (mode) {
+ case IXGBE_64_VM:
+ gpie |= IXGBE_GPIE_VTMODE_64;
+ break;
+ case IXGBE_32_VM:
+ gpie |= IXGBE_GPIE_VTMODE_32;
+ break;
+ default:
+ panic("Unexpected SR-IOV mode %d", mode);
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+
+ /* Enable rx/tx for the PF. */
+ vf_reg = IXGBE_VF_INDEX(adapter->pool);
+ IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg),
+ IXGBE_VF_BIT(adapter->pool));
+ IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg),
+ IXGBE_VF_BIT(adapter->pool));
+
+ /* Allow VM-to-VM communication. */
+ IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
+
+ vt_ctl = IXGBE_VT_CTL_VT_ENABLE | IXGBE_VT_CTL_REPLEN;
+ vt_ctl |= (adapter->pool << IXGBE_VT_CTL_POOL_SHIFT);
+ IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vt_ctl);
+
+ for (i = 0; i < adapter->num_vfs; i++)
+ ixgbe_init_vf(adapter, &adapter->vfs[i]);
+}
+
+
+/*
+** Check the max frame setting of all active VF's
+*/
+static void
+ixgbe_recalculate_max_frame(struct adapter *adapter)
+{
+ struct ixgbe_vf *vf;
+
+ IXGBE_CORE_LOCK_ASSERT(adapter);
+
+ for (int i = 0; i < adapter->num_vfs; i++) {
+ vf = &adapter->vfs[i];
+ if (vf->flags & IXGBE_VF_ACTIVE)
+ ixgbe_update_max_frame(adapter, vf->max_frame_size);
+ }
+}
+
+
+static void
+ixgbe_init_vf(struct adapter *adapter, struct ixgbe_vf *vf)
+{
+ struct ixgbe_hw *hw;
+ uint32_t vf_index, pfmbimr;
+
+ IXGBE_CORE_LOCK_ASSERT(adapter);
+
+ hw = &adapter->hw;
+
+ if (!(vf->flags & IXGBE_VF_ACTIVE))
+ return;
+
+ vf_index = IXGBE_VF_INDEX(vf->pool);
+ pfmbimr = IXGBE_READ_REG(hw, IXGBE_PFMBIMR(vf_index));
+ pfmbimr |= IXGBE_VF_BIT(vf->pool);
+ IXGBE_WRITE_REG(hw, IXGBE_PFMBIMR(vf_index), pfmbimr);
+
+ ixgbe_vf_set_default_vlan(adapter, vf, vf->vlan_tag);
+
+ // XXX multicast addresses
+
+ if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) {
+ ixgbe_set_rar(&adapter->hw, vf->rar_index,
+ vf->ether_addr, vf->pool, TRUE);
+ }
+
+ ixgbe_vf_enable_transmit(adapter, vf);
+ ixgbe_vf_enable_receive(adapter, vf);
+
+ ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG);
+}
+
+static int
+ixgbe_add_vf(device_t dev, u16 vfnum, const nvlist_t *config)
+{
+ struct adapter *adapter;
+ struct ixgbe_vf *vf;
+ const void *mac;
+
+ adapter = device_get_softc(dev);
+
+ KASSERT(vfnum < adapter->num_vfs, ("VF index %d is out of range %d",
+ vfnum, adapter->num_vfs));
+
+ IXGBE_CORE_LOCK(adapter);
+ vf = &adapter->vfs[vfnum];
+ vf->pool= vfnum;
+
+ /* RAR[0] is used by the PF so use vfnum + 1 for VF RAR. */
+ vf->rar_index = vfnum + 1;
+ vf->default_vlan = 0;
+ vf->max_frame_size = ETHER_MAX_LEN;
+ ixgbe_update_max_frame(adapter, vf->max_frame_size);
+
+ if (nvlist_exists_binary(config, "mac-addr")) {
+ mac = nvlist_get_binary(config, "mac-addr", NULL);
+ bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN);
+ if (nvlist_get_bool(config, "allow-set-mac"))
+ vf->flags |= IXGBE_VF_CAP_MAC;
+ } else
+ /*
+ * If the administrator has not specified a MAC address then
+ * we must allow the VF to choose one.
+ */
+ vf->flags |= IXGBE_VF_CAP_MAC;
+
+ vf->flags = IXGBE_VF_ACTIVE;
+
+ ixgbe_init_vf(adapter, vf);
+ IXGBE_CORE_UNLOCK(adapter);
+
+ return (0);
+}
+#endif /* PCI_IOV */
diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c
index a550a856e6f8..cc2d63f1c9ba 100644
--- a/sys/dev/ixgbe/if_ixv.c
+++ b/sys/dev/ixgbe/if_ixv.c
@@ -43,7 +43,7 @@
/*********************************************************************
* Driver version
*********************************************************************/
-char ixv_driver_version[] = "1.2.5";
+char ixv_driver_version[] = "1.4.0";
/*********************************************************************
* PCI Device ID Table
@@ -151,6 +151,10 @@ MODULE_DEPEND(ixv, ether, 1, 1, 1);
** TUNEABLE PARAMETERS:
*/
+/* Number of Queues - do not exceed MSIX vectors - 1 */
+static int ixv_num_queues = 1;
+TUNABLE_INT("hw.ixv.num_queues", &ixv_num_queues);
+
/*
** AIM: Adaptive Interrupt Moderation
** which means that the interrupt rate
@@ -338,6 +342,11 @@ ixv_attach(device_t dev)
ixgbe_reset_hw(hw);
+ /* Get the Mailbox API version */
+ device_printf(dev,"MBX API %d negotiation: %d\n",
+ ixgbe_mbox_api_11,
+ ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11));
+
error = ixgbe_init_hw(hw);
if (error) {
device_printf(dev,"Hardware Initialization Failure\n");
@@ -1313,10 +1322,13 @@ static int
ixv_setup_msix(struct adapter *adapter)
{
device_t dev = adapter->dev;
- int rid, want;
+ int rid, want, msgs;
- /* First try MSI/X */
+ /* Must have at least 2 MSIX vectors */
+ msgs = pci_msix_count(dev);
+ if (msgs < 2)
+ goto out;
rid = PCIR_BAR(3);
adapter->msix_mem = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE);
@@ -1327,11 +1339,16 @@ ixv_setup_msix(struct adapter *adapter)
}
/*
- ** Want two vectors: one for a queue,
+ ** Want vectors for the queues,
** plus an additional for mailbox.
*/
- want = 2;
- if ((pci_alloc_msix(dev, &want) == 0) && (want == 2)) {
+ want = adapter->num_queues + 1;
+ if (want > msgs) {
+ want = msgs;
+ adapter->num_queues = msgs - 1;
+ } else
+ msgs = want;
+ if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
device_printf(adapter->dev,
"Using MSIX interrupts with %d vectors\n", want);
return (want);
@@ -1370,7 +1387,9 @@ ixv_allocate_pci_resources(struct adapter *adapter)
rman_get_bushandle(adapter->pci_mem);
adapter->hw.hw_addr = (u8 *) &adapter->osdep.mem_bus_space_handle;
- adapter->num_queues = 1;
+ /* Pick up the tuneable queues */
+ adapter->num_queues = ixv_num_queues;
+
adapter->hw.back = &adapter->osdep;
/*
@@ -1591,32 +1610,41 @@ ixv_initialize_receive_units(struct adapter *adapter)
{
struct rx_ring *rxr = adapter->rx_rings;
struct ixgbe_hw *hw = &adapter->hw;
- struct ifnet *ifp = adapter->ifp;
- u32 bufsz, fctrl, rxcsum, hlreg;
-
-
- /* Enable broadcasts */
- fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- fctrl |= IXGBE_FCTRL_BAM;
- fctrl |= IXGBE_FCTRL_DPF;
- fctrl |= IXGBE_FCTRL_PMCF;
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+ struct ifnet *ifp = adapter->ifp;
+ u32 bufsz, rxcsum, psrtype;
+ int max_frame;
- /* Set for Jumbo Frames? */
- hlreg = IXGBE_READ_REG(hw, IXGBE_HLREG0);
- if (ifp->if_mtu > ETHERMTU) {
- hlreg |= IXGBE_HLREG0_JUMBOEN;
+ if (ifp->if_mtu > ETHERMTU)
bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
- } else {
- hlreg &= ~IXGBE_HLREG0_JUMBOEN;
+ else
bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
- }
- IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg);
+
+ psrtype = IXGBE_PSRTYPE_TCPHDR | IXGBE_PSRTYPE_UDPHDR |
+ IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_IPV6HDR |
+ IXGBE_PSRTYPE_L2HDR;
+
+ IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype);
+
+ /* Tell PF our expected packet-size */
+ max_frame = ifp->if_mtu + IXGBE_MTU_HDR;
+ ixgbevf_rlpml_set_vf(hw, max_frame);
for (int i = 0; i < adapter->num_queues; i++, rxr++) {
u64 rdba = rxr->rxdma.dma_paddr;
u32 reg, rxdctl;
+ /* Disable the queue */
+ rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i));
+ rxdctl &= ~(IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME);
+ IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl);
+ for (int j = 0; j < 10; j++) {
+ if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) &
+ IXGBE_RXDCTL_ENABLE)
+ msec_delay(1);
+ else
+ break;
+ }
+ wmb();
/* Setup the Base and Length of the Rx Descriptor Ring */
IXGBE_WRITE_REG(hw, IXGBE_VFRDBAL(i),
(rdba & 0x00000000ffffffffULL));
@@ -1625,6 +1653,10 @@ ixv_initialize_receive_units(struct adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(i),
adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc));
+ /* Reset the ring indices */
+ IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), 0);
+
/* Set up the SRRCTL register */
reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i));
reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
@@ -1633,14 +1665,14 @@ ixv_initialize_receive_units(struct adapter *adapter)
reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(i), reg);
- /* Setup the HW Rx Head and Tail Descriptor Pointers */
- IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0);
+ /* Set the Tail Pointer */
IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me),
adapter->num_rx_desc - 1);
+
/* Set the processing limit */
rxr->process_limit = ixv_rx_process_limit;
- /* Set Rx Tail register */
+ /* Capture Rx Tail index */
rxr->tail = IXGBE_VFRDT(rxr->me);
/* Do the queue enabling last */
@@ -2033,9 +2065,7 @@ ixv_add_stats_sysctls(struct adapter *adapter)
SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets",
CTLFLAG_RD, &(txr->total_packets),
"TX Packets");
- SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "tx_bytes",
- CTLFLAG_RD, &(txr->bytes), 0,
- "TX Bytes");
+
SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_no_desc",
CTLFLAG_RD, &(txr->no_desc_avail),
"# of times not enough descriptors were available during TX");
diff --git a/sys/dev/ixgbe/ix_txrx.c b/sys/dev/ixgbe/ix_txrx.c
index bfe16070e374..c20b24e7064c 100644
--- a/sys/dev/ixgbe/ix_txrx.c
+++ b/sys/dev/ixgbe/ix_txrx.c
@@ -578,7 +578,6 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr)
{
struct adapter *adapter = txr->adapter;
struct ixgbe_tx_buf *txbuf;
- int i;
#ifdef DEV_NETMAP
struct netmap_adapter *na = NA(adapter->ifp);
struct netmap_slot *slot;
@@ -601,7 +600,7 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr)
/* Free any existing tx buffers. */
txbuf = txr->tx_buffers;
- for (i = 0; i < txr->num_desc; i++, txbuf++) {
+ for (int i = 0; i < txr->num_desc; i++, txbuf++) {
if (txbuf->m_head != NULL) {
bus_dmamap_sync(txr->txtag, txbuf->map,
BUS_DMASYNC_POSTWRITE);
@@ -622,7 +621,8 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr)
*/
if (slot) {
int si = netmap_idx_n2k(&na->tx_rings[txr->me], i);
- netmap_load_map(na, txr->txtag, txbuf->map, NMB(na, slot + si));
+ netmap_load_map(na, txr->txtag,
+ txbuf->map, NMB(na, slot + si));
}
#endif /* DEV_NETMAP */
/* Clear the EOP descriptor pointer */
@@ -777,8 +777,7 @@ ixgbe_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp,
if (mp->m_flags & M_VLANTAG) {
vtag = htole16(mp->m_pkthdr.ether_vtag);
vlan_macip_lens |= (vtag << IXGBE_ADVTXD_VLAN_SHIFT);
- }
- else if (!IXGBE_IS_X550VF(adapter) && (offload == FALSE))
+ } else if (!IXGBE_IS_X550VF(adapter) && (offload == FALSE))
return (0);
/*
@@ -1379,7 +1378,7 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr)
struct adapter *adapter = rxr->adapter;
device_t dev = adapter->dev;
struct ixgbe_rx_buf *rxbuf;
- int i, bsize, error;
+ int bsize, error;
bsize = sizeof(struct ixgbe_rx_buf) * rxr->num_desc;
if (!(rxr->rx_buffers =
@@ -1406,7 +1405,7 @@ ixgbe_allocate_receive_buffers(struct rx_ring *rxr)
goto fail;
}
- for (i = 0; i < rxr->num_desc; i++, rxbuf++) {
+ for (int i = 0; i < rxr->num_desc; i++, rxbuf++) {
rxbuf = &rxr->rx_buffers[i];
error = bus_dmamap_create(rxr->ptag, 0, &rxbuf->pmap);
if (error) {
@@ -1428,9 +1427,8 @@ static void
ixgbe_free_receive_ring(struct rx_ring *rxr)
{
struct ixgbe_rx_buf *rxbuf;
- int i;
- for (i = 0; i < rxr->num_desc; i++) {
+ for (int i = 0; i < rxr->num_desc; i++) {
rxbuf = &rxr->rx_buffers[i];
if (rxbuf->buf != NULL) {
bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
@@ -2140,6 +2138,9 @@ ixgbe_allocate_queues(struct adapter *adapter)
struct rx_ring *rxr;
int rsize, tsize, error = IXGBE_SUCCESS;
int txconf = 0, rxconf = 0;
+#ifdef PCI_IOV
+ enum ixgbe_iov_mode iov_mode;
+#endif
/* First allocate the top level queue structs */
if (!(adapter->queues =
@@ -2172,6 +2173,12 @@ ixgbe_allocate_queues(struct adapter *adapter)
tsize = roundup2(adapter->num_tx_desc *
sizeof(union ixgbe_adv_tx_desc), DBA_ALIGN);
+#ifdef PCI_IOV
+ iov_mode = ixgbe_get_iov_mode(adapter);
+ adapter->pool = ixgbe_max_vfs(iov_mode);
+#else
+ adapter->pool = 0;
+#endif
/*
* Now set up the TX queues, txconf is needed to handle the
* possibility that things fail midcourse and we need to
@@ -2181,7 +2188,11 @@ ixgbe_allocate_queues(struct adapter *adapter)
/* Set up some basics */
txr = &adapter->tx_rings[i];
txr->adapter = adapter;
+#ifdef PCI_IOV
+ txr->me = ixgbe_pf_que_index(iov_mode, i);
+#else
txr->me = i;
+#endif
txr->num_desc = adapter->num_tx_desc;
/* Initialize the TX side lock */
@@ -2228,7 +2239,11 @@ ixgbe_allocate_queues(struct adapter *adapter)
rxr = &adapter->rx_rings[i];
/* Set up some basics */
rxr->adapter = adapter;
+#ifdef PCI_IOV
+ rxr->me = ixgbe_pf_que_index(iov_mode, i);
+#else
rxr->me = i;
+#endif
rxr->num_desc = adapter->num_rx_desc;
/* Initialize the RX side lock */
diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h
index 44e7c3c26802..7f8aac59cc7e 100644
--- a/sys/dev/ixgbe/ixgbe.h
+++ b/sys/dev/ixgbe/ixgbe.h
@@ -92,11 +92,22 @@
#include <machine/smp.h>
#include <sys/sbuf.h>
+#ifdef PCI_IOV
+#include <sys/nv.h>
+#include <sys/iov_schema.h>
+#include <dev/pci/pci_iov.h>
+#endif
+
#include "ixgbe_api.h"
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
#include "ixgbe_vf.h"
+#ifdef PCI_IOV
+#include "ixgbe_common.h"
+#include "ixgbe_mbx.h"
+#endif
+
/* Tunables */
/*
@@ -244,6 +255,29 @@
(_adapter->hw.mac.type == ixgbe_mac_X540_vf) || \
(_adapter->hw.mac.type == ixgbe_mac_82599_vf))
+#ifdef PCI_IOV
+#define IXGBE_VF_INDEX(vmdq) ((vmdq) / 32)
+#define IXGBE_VF_BIT(vmdq) (1 << ((vmdq) % 32))
+
+#define IXGBE_VT_MSG_MASK 0xFFFF
+
+#define IXGBE_VT_MSGINFO(msg) \
+ (((msg) & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT)
+
+#define IXGBE_VF_GET_QUEUES_RESP_LEN 5
+
+#define IXGBE_API_VER_1_0 0
+#define IXGBE_API_VER_2_0 1 /* Solaris API. Not supported. */
+#define IXGBE_API_VER_1_1 2
+#define IXGBE_API_VER_UNKNOWN UINT16_MAX
+
+enum ixgbe_iov_mode {
+ IXGBE_64_VM,
+ IXGBE_32_VM,
+ IXGBE_NO_VM
+};
+#endif /* PCI_IOV */
+
/*
*****************************************************************************
@@ -262,6 +296,7 @@ typedef struct _ixgbe_vendor_info_t {
unsigned int index;
} ixgbe_vendor_info_t;
+
struct ixgbe_tx_buf {
union ixgbe_adv_tx_desc *eop;
struct mbuf *m_head;
@@ -290,6 +325,11 @@ struct ixgbe_dma_alloc {
int dma_nseg;
};
+struct ixgbe_mc_addr {
+ u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+ u32 vmdq;
+};
+
/*
** Driver queue struct: this is the interrupt container
** for the associated tx and rx ring.
@@ -387,6 +427,28 @@ struct rx_ring {
#endif
};
+#ifdef PCI_IOV
+#define IXGBE_VF_CTS (1 << 0) /* VF is clear to send. */
+#define IXGBE_VF_CAP_MAC (1 << 1) /* VF is permitted to change MAC. */
+#define IXGBE_VF_CAP_VLAN (1 << 2) /* VF is permitted to join vlans. */
+#define IXGBE_VF_ACTIVE (1 << 3) /* VF is active. */
+
+#define IXGBE_MAX_VF_MC 30 /* Max number of multicast entries */
+
+struct ixgbe_vf {
+ u_int pool;
+ u_int rar_index;
+ u_int max_frame_size;
+ uint32_t flags;
+ uint8_t ether_addr[ETHER_ADDR_LEN];
+ uint16_t mc_hash[IXGBE_MAX_VF_MC];
+ uint16_t num_mc_hashes;
+ uint16_t default_vlan;
+ uint16_t vlan_tag;
+ uint16_t api_ver;
+};
+#endif /* PCI_IOV */
+
/* Our adapter structure */
struct adapter {
struct ifnet *ifp;
@@ -438,8 +500,8 @@ struct adapter {
bool link_up;
u32 vector;
u16 dmac;
- bool eee_support;
bool eee_enabled;
+ u32 phy_layer;
/* Power management-related */
bool wol_support;
@@ -453,6 +515,9 @@ struct adapter {
struct task link_task; /* Link tasklet */
struct task mod_task; /* SFP tasklet */
struct task msf_task; /* Multispeed Fiber */
+#ifdef PCI_IOV
+ struct task mbx_task; /* VF -> PF mailbox interrupt */
+#endif /* PCI_IOV */
#ifdef IXGBE_FDIR
int fdir_reinit;
struct task fdir_task;
@@ -484,8 +549,12 @@ struct adapter {
u32 num_rx_desc;
/* Multicast array memory */
- u8 *mta;
-
+ struct ixgbe_mc_addr *mta;
+ int num_vfs;
+ int pool;
+#ifdef PCI_IOV
+ struct ixgbe_vf *vfs;
+#endif
/* Misc stats maintained by the driver */
unsigned long dropped_pkts;
@@ -671,4 +740,150 @@ bool ixgbe_rxeof(struct ix_queue *);
int ixgbe_dma_malloc(struct adapter *,
bus_size_t, struct ixgbe_dma_alloc *, int);
void ixgbe_dma_free(struct adapter *, struct ixgbe_dma_alloc *);
+
+#ifdef PCI_IOV
+
+static inline boolean_t
+ixgbe_vf_mac_changed(struct ixgbe_vf *vf, const uint8_t *mac)
+{
+ return (bcmp(mac, vf->ether_addr, ETHER_ADDR_LEN) != 0);
+}
+
+static inline void
+ixgbe_send_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
+{
+
+ if (vf->flags & IXGBE_VF_CTS)
+ msg |= IXGBE_VT_MSGTYPE_CTS;
+
+ ixgbe_write_mbx(&adapter->hw, &msg, 1, vf->pool);
+}
+
+static inline void
+ixgbe_send_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
+{
+ msg &= IXGBE_VT_MSG_MASK;
+ ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_ACK);
+}
+
+static inline void
+ixgbe_send_vf_nack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
+{
+ msg &= IXGBE_VT_MSG_MASK;
+ ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_NACK);
+}
+
+static inline void
+ixgbe_process_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf)
+{
+ if (!(vf->flags & IXGBE_VF_CTS))
+ ixgbe_send_vf_nack(adapter, vf, 0);
+}
+
+static inline enum ixgbe_iov_mode
+ixgbe_get_iov_mode(struct adapter *adapter)
+{
+ if (adapter->num_vfs == 0)
+ return (IXGBE_NO_VM);
+ if (adapter->num_queues <= 2)
+ return (IXGBE_64_VM);
+ else if (adapter->num_queues <= 4)
+ return (IXGBE_32_VM);
+ else
+ return (IXGBE_NO_VM);
+}
+
+static inline u16
+ixgbe_max_vfs(enum ixgbe_iov_mode mode)
+{
+ /*
+ * We return odd numbers below because we
+ * reserve 1 VM's worth of queues for the PF.
+ */
+ switch (mode) {
+ case IXGBE_64_VM:
+ return (63);
+ case IXGBE_32_VM:
+ return (31);
+ case IXGBE_NO_VM:
+ default:
+ return (0);
+ }
+}
+
+static inline int
+ixgbe_vf_queues(enum ixgbe_iov_mode mode)
+{
+ switch (mode) {
+ case IXGBE_64_VM:
+ return (2);
+ case IXGBE_32_VM:
+ return (4);
+ case IXGBE_NO_VM:
+ default:
+ return (0);
+ }
+}
+
+static inline int
+ixgbe_vf_que_index(enum ixgbe_iov_mode mode, u32 vfnum, int num)
+{
+ return ((vfnum * ixgbe_vf_queues(mode)) + num);
+}
+
+static inline int
+ixgbe_pf_que_index(enum ixgbe_iov_mode mode, int num)
+{
+ return (ixgbe_vf_que_index(mode, ixgbe_max_vfs(mode), num));
+}
+
+static inline void
+ixgbe_update_max_frame(struct adapter * adapter, int max_frame)
+{
+ if (adapter->max_frame_size < max_frame)
+ adapter->max_frame_size = max_frame;
+}
+
+static inline u32
+ixgbe_get_mrqc(enum ixgbe_iov_mode mode)
+{
+ u32 mrqc = 0;
+ switch (mode) {
+ case IXGBE_64_VM:
+ mrqc = IXGBE_MRQC_VMDQRSS64EN;
+ break;
+ case IXGBE_32_VM:
+ mrqc = IXGBE_MRQC_VMDQRSS32EN;
+ break;
+ case IXGBE_NO_VM:
+ mrqc = 0;
+ break;
+ default:
+ panic("Unexpected SR-IOV mode %d", mode);
+ }
+ return(mrqc);
+}
+
+
+static inline u32
+ixgbe_get_mtqc(enum ixgbe_iov_mode mode)
+{
+ uint32_t mtqc = 0;
+ switch (mode) {
+ case IXGBE_64_VM:
+ mtqc |= IXGBE_MTQC_64VF | IXGBE_MTQC_VT_ENA;
+ break;
+ case IXGBE_32_VM:
+ mtqc |= IXGBE_MTQC_32VF | IXGBE_MTQC_VT_ENA;
+ break;
+ case IXGBE_NO_VM:
+ mtqc = IXGBE_MTQC_64Q_1PB;
+ break;
+ default:
+ panic("Unexpected SR-IOV mode %d", mode);
+ }
+ return(mtqc);
+}
+#endif /* PCI_IOV */
+
#endif /* _IXGBE_H_ */
diff --git a/sys/dev/ixgbe/ixgbe_mbx.h b/sys/dev/ixgbe/ixgbe_mbx.h
index ea75cbeeb5a6..a4a78eb6ede2 100644
--- a/sys/dev/ixgbe/ixgbe_mbx.h
+++ b/sys/dev/ixgbe/ixgbe_mbx.h
@@ -80,6 +80,21 @@
/* bits 23:16 are used for extra info for certain messages */
#define IXGBE_VT_MSGINFO_MASK (0xFF << IXGBE_VT_MSGINFO_SHIFT)
+/* definitions to support mailbox API version negotiation */
+
+/*
+ * each element denotes a version of the API; existing numbers may not
+ * change; any additions must go at the end
+ */
+enum ixgbe_pfvf_api_rev {
+ ixgbe_mbox_api_10, /* API version 1.0, linux/freebsd VF driver */
+ ixgbe_mbox_api_20, /* API version 2.0, solaris Phase1 VF driver */
+ ixgbe_mbox_api_11, /* API version 1.1, linux/freebsd VF driver */
+ /* This value should always be last */
+ ixgbe_mbox_api_unknown, /* indicates that API version is not known */
+};
+
+/* mailbox API, legacy requests */
#define IXGBE_VF_RESET 0x01 /* VF requests reset */
#define IXGBE_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
@@ -106,6 +121,18 @@
#define IXGBE_PF_CONTROL_MSG 0x0100 /* PF control message */
+/* mailbox API, version 2.0 VF requests */
+#define IXGBE_VF_API_NEGOTIATE 0x08 /* negotiate API version */
+#define IXGBE_VF_GET_QUEUES 0x09 /* get queue configuration */
+#define IXGBE_VF_ENABLE_MACADDR 0x0A /* enable MAC address */
+#define IXGBE_VF_DISABLE_MACADDR 0x0B /* disable MAC address */
+#define IXGBE_VF_GET_MACADDRS 0x0C /* get all configured MAC addrs */
+#define IXGBE_VF_SET_MCAST_PROMISC 0x0D /* enable multicast promiscuous */
+#define IXGBE_VF_GET_MTU 0x0E /* get bounds on MTU */
+#define IXGBE_VF_SET_MTU 0x0F /* set a specific MTU */
+
+/* mailbox API, version 2.0 PF requests */
+#define IXGBE_PF_TRANSPARENT_VLAN 0x0101 /* enable transparent vlan */
#define IXGBE_VF_MBX_INIT_TIMEOUT 2000 /* number of retries on mailbox */
#define IXGBE_VF_MBX_INIT_DELAY 500 /* microseconds between retries */
diff --git a/sys/dev/ixgbe/ixgbe_vf.c b/sys/dev/ixgbe/ixgbe_vf.c
index c010cf4357dd..2ce4d32a303b 100644
--- a/sys/dev/ixgbe/ixgbe_vf.c
+++ b/sys/dev/ixgbe/ixgbe_vf.c
@@ -185,6 +185,8 @@ s32 ixgbe_reset_hw_vf(struct ixgbe_hw *hw)
/* Call adapter stop to disable tx/rx and clear interrupts */
hw->mac.ops.stop_adapter(hw);
+ /* reset the api version */
+ hw->api_version = ixgbe_mbox_api_10;
DEBUGOUT("Issuing a function level reset to MAC\n");
@@ -666,6 +668,57 @@ int ixgbevf_negotiate_api_version(struct ixgbe_hw *hw, int api)
int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
unsigned int *default_tc)
{
- UNREFERENCED_3PARAMETER(hw, num_tcs, default_tc);
- return IXGBE_SUCCESS;
+ int err;
+ u32 msg[5];
+
+ /* do nothing if API doesn't support ixgbevf_get_queues */
+ switch (hw->api_version) {
+ case ixgbe_mbox_api_11:
+ break;
+ default:
+ return 0;
+ }
+
+ /* Fetch queue configuration from the PF */
+ msg[0] = IXGBE_VF_GET_QUEUES;
+ msg[1] = msg[2] = msg[3] = msg[4] = 0;
+ err = hw->mbx.ops.write_posted(hw, msg, 5, 0);
+
+ if (!err)
+ err = hw->mbx.ops.read_posted(hw, msg, 5, 0);
+
+ if (!err) {
+ msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+ /*
+ * if we we didn't get an ACK there must have been
+ * some sort of mailbox error so we should treat it
+ * as such
+ */
+ if (msg[0] != (IXGBE_VF_GET_QUEUES | IXGBE_VT_MSGTYPE_ACK))
+ return IXGBE_ERR_MBX;
+
+ /* record and validate values from message */
+ hw->mac.max_tx_queues = msg[IXGBE_VF_TX_QUEUES];
+ if (hw->mac.max_tx_queues == 0 ||
+ hw->mac.max_tx_queues > IXGBE_VF_MAX_TX_QUEUES)
+ hw->mac.max_tx_queues = IXGBE_VF_MAX_TX_QUEUES;
+
+ hw->mac.max_rx_queues = msg[IXGBE_VF_RX_QUEUES];
+ if (hw->mac.max_rx_queues == 0 ||
+ hw->mac.max_rx_queues > IXGBE_VF_MAX_RX_QUEUES)
+ hw->mac.max_rx_queues = IXGBE_VF_MAX_RX_QUEUES;
+
+ *num_tcs = msg[IXGBE_VF_TRANS_VLAN];
+ /* in case of unknown state assume we cannot tag frames */
+ if (*num_tcs > hw->mac.max_rx_queues)
+ *num_tcs = 1;
+
+ *default_tc = msg[IXGBE_VF_DEF_QUEUE];
+ /* default to queue 0 on out-of-bounds queue number */
+ if (*default_tc >= hw->mac.max_tx_queues)
+ *default_tc = 0;
+ }
+
+ return err;
}
diff --git a/sys/dev/ixl/i40e_adminq.c b/sys/dev/ixl/i40e_adminq.c
index d769c45c0dbb..5eacdc4e31a5 100644
--- a/sys/dev/ixl/i40e_adminq.c
+++ b/sys/dev/ixl/i40e_adminq.c
@@ -315,8 +315,12 @@ static enum i40e_status_code i40e_config_asq_regs(struct i40e_hw *hw)
wr32(hw, hw->aq.asq.tail, 0);
/* set starting point */
- wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
- I40E_PF_ATQLEN_ATQENABLE_MASK));
+ if (!i40e_is_vf(hw))
+ wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
+ I40E_PF_ATQLEN_ATQENABLE_MASK));
+ if (i40e_is_vf(hw))
+ wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
+ I40E_VF_ATQLEN1_ATQENABLE_MASK));
wr32(hw, hw->aq.asq.bal, I40E_LO_DWORD(hw->aq.asq.desc_buf.pa));
wr32(hw, hw->aq.asq.bah, I40E_HI_DWORD(hw->aq.asq.desc_buf.pa));
@@ -344,8 +348,12 @@ static enum i40e_status_code i40e_config_arq_regs(struct i40e_hw *hw)
wr32(hw, hw->aq.arq.tail, 0);
/* set starting point */
- wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
- I40E_PF_ARQLEN_ARQENABLE_MASK));
+ if (!i40e_is_vf(hw))
+ wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
+ I40E_PF_ARQLEN_ARQENABLE_MASK));
+ if (i40e_is_vf(hw))
+ wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
+ I40E_VF_ARQLEN1_ARQENABLE_MASK));
wr32(hw, hw->aq.arq.bal, I40E_LO_DWORD(hw->aq.arq.desc_buf.pa));
wr32(hw, hw->aq.arq.bah, I40E_HI_DWORD(hw->aq.arq.desc_buf.pa));
@@ -559,6 +567,7 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw)
{
enum i40e_status_code ret_code;
u16 eetrack_lo, eetrack_hi;
+ u16 cfg_ptr, oem_hi, oem_lo;
int retry = 0;
/* verify input for valid configuration */
if ((hw->aq.num_arq_entries == 0) ||
@@ -619,6 +628,12 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw)
i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
+ i40e_read_nvm_word(hw, I40E_SR_BOOT_CONFIG_PTR, &cfg_ptr);
+ i40e_read_nvm_word(hw, (cfg_ptr + I40E_NVM_OEM_VER_OFF),
+ &oem_hi);
+ i40e_read_nvm_word(hw, (cfg_ptr + (I40E_NVM_OEM_VER_OFF + 1)),
+ &oem_lo);
+ hw->nvm.oem_ver = ((u32)oem_hi << 16) | oem_lo;
if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
ret_code = I40E_ERR_FIRMWARE_API_VERSION;
@@ -669,6 +684,9 @@ enum i40e_status_code i40e_shutdown_adminq(struct i40e_hw *hw)
i40e_destroy_spinlock(&hw->aq.asq_spinlock);
i40e_destroy_spinlock(&hw->aq.arq_spinlock);
+ if (hw->nvm_buff.va)
+ i40e_free_virt_mem(hw, &hw->nvm_buff);
+
return ret_code;
}
@@ -688,16 +706,16 @@ u16 i40e_clean_asq(struct i40e_hw *hw)
desc = I40E_ADMINQ_DESC(*asq, ntc);
details = I40E_ADMINQ_DETAILS(*asq, ntc);
+
while (rd32(hw, hw->aq.asq.head) != ntc) {
i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
- "%s: ntc %d head %d.\n", __FUNCTION__, ntc,
- rd32(hw, hw->aq.asq.head));
+ "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head));
if (details->callback) {
I40E_ADMINQ_CALLBACK cb_func =
(I40E_ADMINQ_CALLBACK)details->callback;
- i40e_memcpy(&desc_cb, desc,
- sizeof(struct i40e_aq_desc), I40E_DMA_TO_DMA);
+ i40e_memcpy(&desc_cb, desc, sizeof(struct i40e_aq_desc),
+ I40E_DMA_TO_DMA);
cb_func(hw, &desc_cb);
}
i40e_memset(desc, 0, sizeof(*desc), I40E_DMA_MEM);
@@ -755,6 +773,8 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw,
u16 retval = 0;
u32 val = 0;
+ hw->aq.asq_last_status = I40E_AQ_RC_OK;
+
val = rd32(hw, hw->aq.asq.head);
if (val >= hw->aq.num_asq_entries) {
i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
@@ -912,6 +932,11 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw,
"AQTX: desc and buffer writeback:\n");
i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size);
+ /* save writeback aq if requested */
+ if (details->wb_desc)
+ i40e_memcpy(details->wb_desc, desc_on_ring,
+ sizeof(struct i40e_aq_desc), I40E_DMA_TO_NONDMA);
+
/* update the error if time out occurred */
if ((!cmd_completed) &&
(!details->async && !details->postpone)) {
@@ -971,7 +996,10 @@ enum i40e_status_code i40e_clean_arq_element(struct i40e_hw *hw,
i40e_acquire_spinlock(&hw->aq.arq_spinlock);
/* set next_to_use to head */
- ntu = (rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK);
+ if (!i40e_is_vf(hw))
+ ntu = (rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK);
+ if (i40e_is_vf(hw))
+ ntu = (rd32(hw, hw->aq.arq.head) & I40E_VF_ARQH1_ARQH_MASK);
if (ntu == ntc) {
/* nothing to do - shouldn't need to update ring's values */
ret_code = I40E_ERR_ADMIN_QUEUE_NO_WORK;
@@ -1040,6 +1068,19 @@ clean_arq_element_out:
i40e_release_nvm(hw);
hw->aq.nvm_release_on_done = FALSE;
}
+
+ switch (hw->nvmupd_state) {
+ case I40E_NVMUPD_STATE_INIT_WAIT:
+ hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+ break;
+
+ case I40E_NVMUPD_STATE_WRITE_WAIT:
+ hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
+ break;
+
+ default:
+ break;
+ }
}
return ret_code;
@@ -1051,9 +1092,6 @@ void i40e_resume_aq(struct i40e_hw *hw)
hw->aq.asq.next_to_use = 0;
hw->aq.asq.next_to_clean = 0;
-#if (I40E_VF_ATQLEN_ATQENABLE_MASK != I40E_PF_ATQLEN_ATQENABLE_MASK)
-#error I40E_VF_ATQLEN_ATQENABLE_MASK != I40E_PF_ATQLEN_ATQENABLE_MASK
-#endif
i40e_config_asq_regs(hw);
hw->aq.arq.next_to_use = 0;
diff --git a/sys/dev/ixl/i40e_adminq.h b/sys/dev/ixl/i40e_adminq.h
index 9db4c9d21965..76dab8eb9978 100644
--- a/sys/dev/ixl/i40e_adminq.h
+++ b/sys/dev/ixl/i40e_adminq.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2013-2014, Intel Corporation
+ Copyright (c) 2013-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -77,6 +77,7 @@ struct i40e_asq_cmd_details {
u16 flags_dis;
bool async;
bool postpone;
+ struct i40e_aq_desc *wb_desc;
};
#define I40E_ADMINQ_DETAILS(R, i) \
diff --git a/sys/dev/ixl/i40e_adminq_cmd.h b/sys/dev/ixl/i40e_adminq_cmd.h
index 0d52883e70d7..f1f267e9f18b 100644
--- a/sys/dev/ixl/i40e_adminq_cmd.h
+++ b/sys/dev/ixl/i40e_adminq_cmd.h
@@ -42,7 +42,11 @@
*/
#define I40E_FW_API_VERSION_MAJOR 0x0001
-#define I40E_FW_API_VERSION_MINOR 0x0002
+#ifdef X722_SUPPORT
+#define I40E_FW_API_VERSION_MINOR 0x0003
+#else
+#define I40E_FW_API_VERSION_MINOR 0x0004
+#endif
struct i40e_aq_desc {
__le16 flags;
@@ -140,12 +144,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_list_func_capabilities = 0x000A,
i40e_aqc_opc_list_dev_capabilities = 0x000B,
- i40e_aqc_opc_set_cppm_configuration = 0x0103,
- i40e_aqc_opc_set_arp_proxy_entry = 0x0104,
- i40e_aqc_opc_set_ns_proxy_entry = 0x0105,
-
/* LAA */
- i40e_aqc_opc_mng_laa = 0x0106, /* AQ obsolete */
i40e_aqc_opc_mac_address_read = 0x0107,
i40e_aqc_opc_mac_address_write = 0x0108,
@@ -240,6 +239,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_nvm_update = 0x0703,
i40e_aqc_opc_nvm_config_read = 0x0704,
i40e_aqc_opc_nvm_config_write = 0x0705,
+ i40e_aqc_opc_oem_post_update = 0x0720,
/* virtualization commands */
i40e_aqc_opc_send_msg_to_pf = 0x0801,
@@ -270,7 +270,12 @@ enum i40e_admin_queue_opc {
/* Tunnel commands */
i40e_aqc_opc_add_udp_tunnel = 0x0B00,
i40e_aqc_opc_del_udp_tunnel = 0x0B01,
- i40e_aqc_opc_tunnel_key_structure = 0x0B10,
+#ifdef X722_SUPPORT
+ i40e_aqc_opc_set_rss_key = 0x0B02,
+ i40e_aqc_opc_set_rss_lut = 0x0B03,
+ i40e_aqc_opc_get_rss_key = 0x0B04,
+ i40e_aqc_opc_get_rss_lut = 0x0B05,
+#endif
/* Async Events */
i40e_aqc_opc_event_lan_overflow = 0x1001,
@@ -282,8 +287,6 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_oem_ocbb_initialize = 0xFE03,
/* debug commands */
- i40e_aqc_opc_debug_get_deviceid = 0xFF00,
- i40e_aqc_opc_debug_set_mode = 0xFF01,
i40e_aqc_opc_debug_read_reg = 0xFF03,
i40e_aqc_opc_debug_write_reg = 0xFF04,
i40e_aqc_opc_debug_modify_reg = 0xFF07,
@@ -517,7 +520,8 @@ struct i40e_aqc_mac_address_read {
#define I40E_AQC_SAN_ADDR_VALID 0x20
#define I40E_AQC_PORT_ADDR_VALID 0x40
#define I40E_AQC_WOL_ADDR_VALID 0x80
-#define I40E_AQC_ADDR_VALID_MASK 0xf0
+#define I40E_AQC_MC_MAG_EN_VALID 0x100
+#define I40E_AQC_ADDR_VALID_MASK 0x1F0
u8 reserved[6];
__le32 addr_high;
__le32 addr_low;
@@ -540,7 +544,9 @@ struct i40e_aqc_mac_address_write {
#define I40E_AQC_WRITE_TYPE_LAA_ONLY 0x0000
#define I40E_AQC_WRITE_TYPE_LAA_WOL 0x4000
#define I40E_AQC_WRITE_TYPE_PORT 0x8000
-#define I40E_AQC_WRITE_TYPE_MASK 0xc000
+#define I40E_AQC_WRITE_TYPE_UPDATE_MC_MAG 0xC000
+#define I40E_AQC_WRITE_TYPE_MASK 0xC000
+
__le16 mac_sah;
__le32 mac_sal;
u8 reserved[8];
@@ -834,8 +840,16 @@ struct i40e_aqc_vsi_properties_data {
I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT)
/* queueing option section */
u8 queueing_opt_flags;
+#ifdef X722_SUPPORT
+#define I40E_AQ_VSI_QUE_OPT_MULTICAST_UDP_ENA 0x04
+#define I40E_AQ_VSI_QUE_OPT_UNICAST_UDP_ENA 0x08
+#endif
#define I40E_AQ_VSI_QUE_OPT_TCP_ENA 0x10
#define I40E_AQ_VSI_QUE_OPT_FCOE_ENA 0x20
+#ifdef X722_SUPPORT
+#define I40E_AQ_VSI_QUE_OPT_RSS_LUT_PF 0x00
+#define I40E_AQ_VSI_QUE_OPT_RSS_LUT_VSI 0x40
+#endif
u8 queueing_opt_reserved[3];
/* scheduler section */
u8 up_enable_bits;
@@ -1076,6 +1090,7 @@ struct i40e_aqc_set_vsi_promiscuous_modes {
__le16 seid;
#define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF
__le16 vlan_tag;
+#define I40E_AQC_SET_VSI_VLAN_MASK 0x0FFF
#define I40E_AQC_SET_VSI_VLAN_VALID 0x8000
u8 reserved[8];
};
@@ -1725,11 +1740,13 @@ struct i40e_aqc_get_link_status {
u8 phy_type; /* i40e_aq_phy_type */
u8 link_speed; /* i40e_aq_link_speed */
u8 link_info;
-#define I40E_AQ_LINK_UP 0x01
+#define I40E_AQ_LINK_UP 0x01 /* obsolete */
+#define I40E_AQ_LINK_UP_FUNCTION 0x01
#define I40E_AQ_LINK_FAULT 0x02
#define I40E_AQ_LINK_FAULT_TX 0x04
#define I40E_AQ_LINK_FAULT_RX 0x08
#define I40E_AQ_LINK_FAULT_REMOTE 0x10
+#define I40E_AQ_LINK_UP_PORT 0x20
#define I40E_AQ_MEDIA_AVAILABLE 0x40
#define I40E_AQ_SIGNAL_DETECT 0x80
u8 an_info;
@@ -1891,6 +1908,26 @@ struct i40e_aqc_nvm_config_data_immediate_field {
I40E_CHECK_STRUCT_LEN(0xc, i40e_aqc_nvm_config_data_immediate_field);
+/* OEM Post Update (indirect 0x0720)
+ * no command data struct used
+ */
+ struct i40e_aqc_nvm_oem_post_update {
+#define I40E_AQ_NVM_OEM_POST_UPDATE_EXTERNAL_DATA 0x01
+ u8 sel_data;
+ u8 reserved[7];
+};
+
+I40E_CHECK_STRUCT_LEN(0x8, i40e_aqc_nvm_oem_post_update);
+
+struct i40e_aqc_nvm_oem_post_update_buffer {
+ u8 str_len;
+ u8 dev_addr;
+ __le16 eeprom_addr;
+ u8 data[36];
+};
+
+I40E_CHECK_STRUCT_LEN(0x28, i40e_aqc_nvm_oem_post_update_buffer);
+
/* Send to PF command (indirect 0x0801) id is only used by PF
* Send to VF command (indirect 0x0802) id is only used by PF
* Send to Peer PF command (indirect 0x0803)
@@ -2064,12 +2101,28 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start);
#define I40E_AQC_CEE_APP_ISCSI_MASK (0x7 << I40E_AQC_CEE_APP_ISCSI_SHIFT)
#define I40E_AQC_CEE_APP_FIP_SHIFT 0x8
#define I40E_AQC_CEE_APP_FIP_MASK (0x7 << I40E_AQC_CEE_APP_FIP_SHIFT)
+
#define I40E_AQC_CEE_PG_STATUS_SHIFT 0x0
#define I40E_AQC_CEE_PG_STATUS_MASK (0x7 << I40E_AQC_CEE_PG_STATUS_SHIFT)
#define I40E_AQC_CEE_PFC_STATUS_SHIFT 0x3
#define I40E_AQC_CEE_PFC_STATUS_MASK (0x7 << I40E_AQC_CEE_PFC_STATUS_SHIFT)
#define I40E_AQC_CEE_APP_STATUS_SHIFT 0x8
#define I40E_AQC_CEE_APP_STATUS_MASK (0x7 << I40E_AQC_CEE_APP_STATUS_SHIFT)
+#define I40E_AQC_CEE_FCOE_STATUS_SHIFT 0x8
+#define I40E_AQC_CEE_FCOE_STATUS_MASK (0x7 << I40E_AQC_CEE_FCOE_STATUS_SHIFT)
+#define I40E_AQC_CEE_ISCSI_STATUS_SHIFT 0xB
+#define I40E_AQC_CEE_ISCSI_STATUS_MASK (0x7 << I40E_AQC_CEE_ISCSI_STATUS_SHIFT)
+#define I40E_AQC_CEE_FIP_STATUS_SHIFT 0x10
+#define I40E_AQC_CEE_FIP_STATUS_MASK (0x7 << I40E_AQC_CEE_FIP_STATUS_SHIFT)
+
+/* struct i40e_aqc_get_cee_dcb_cfg_v1_resp was originally defined with
+ * word boundary layout issues, which the Linux compilers silently deal
+ * with by adding padding, making the actual struct larger than designed.
+ * However, the FW compiler for the NIC is less lenient and complains
+ * about the struct. Hence, the struct defined here has an extra byte in
+ * fields reserved3 and reserved4 to directly acknowledge that padding,
+ * and the new length is used in the length check macro.
+ */
struct i40e_aqc_get_cee_dcb_cfg_v1_resp {
u8 reserved1;
u8 oper_num_tc;
@@ -2077,9 +2130,9 @@ struct i40e_aqc_get_cee_dcb_cfg_v1_resp {
u8 reserved2;
u8 oper_tc_bw[8];
u8 oper_pfc_en;
- u8 reserved3;
+ u8 reserved3[2];
__le16 oper_app_prio;
- u8 reserved4;
+ u8 reserved4[2];
__le16 tlv_status;
};
@@ -2168,6 +2221,48 @@ struct i40e_aqc_del_udp_tunnel_completion {
};
I40E_CHECK_CMD_LENGTH(i40e_aqc_del_udp_tunnel_completion);
+#ifdef X722_SUPPORT
+
+struct i40e_aqc_get_set_rss_key {
+#define I40E_AQC_SET_RSS_KEY_VSI_VALID (0x1 << 15)
+#define I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT 0
+#define I40E_AQC_SET_RSS_KEY_VSI_ID_MASK (0x3FF << \
+ I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT)
+ __le16 vsi_id;
+ u8 reserved[6];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_get_set_rss_key);
+
+struct i40e_aqc_get_set_rss_key_data {
+ u8 standard_rss_key[0x28];
+ u8 extended_hash_key[0xc];
+};
+
+I40E_CHECK_STRUCT_LEN(0x34, i40e_aqc_get_set_rss_key_data);
+
+struct i40e_aqc_get_set_rss_lut {
+#define I40E_AQC_SET_RSS_LUT_VSI_VALID (0x1 << 15)
+#define I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT 0
+#define I40E_AQC_SET_RSS_LUT_VSI_ID_MASK (0x3FF << \
+ I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT)
+ __le16 vsi_id;
+#define I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT 0
+#define I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK (0x1 << \
+ I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT)
+
+#define I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI 0
+#define I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF 1
+ __le16 flags;
+ u8 reserved[4];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_get_set_rss_lut);
+#endif
/* tunnel key structure 0x0B10 */
diff --git a/sys/dev/ixl/i40e_common.c b/sys/dev/ixl/i40e_common.c
index 777ecef9343a..2a5f49902077 100644
--- a/sys/dev/ixl/i40e_common.c
+++ b/sys/dev/ixl/i40e_common.c
@@ -62,9 +62,24 @@ enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
case I40E_DEV_ID_QSFP_B:
case I40E_DEV_ID_QSFP_C:
case I40E_DEV_ID_10G_BASE_T:
+ case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_20G_KR2:
+ case I40E_DEV_ID_20G_KR2_A:
hw->mac.type = I40E_MAC_XL710;
break;
+#ifdef X722_SUPPORT
+ case I40E_DEV_ID_SFP_X722:
+ case I40E_DEV_ID_1G_BASE_T_X722:
+ case I40E_DEV_ID_10G_BASE_T_X722:
+ hw->mac.type = I40E_MAC_X722;
+ break;
+#endif
+#ifdef X722_SUPPORT
+ case I40E_DEV_ID_X722_VF:
+ case I40E_DEV_ID_X722_VF_HV:
+ hw->mac.type = I40E_MAC_X722_VF;
+ break;
+#endif
case I40E_DEV_ID_VF:
case I40E_DEV_ID_VF_HV:
hw->mac.type = I40E_MAC_VF;
@@ -83,6 +98,212 @@ enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
}
/**
+ * i40e_aq_str - convert AQ err code to a string
+ * @hw: pointer to the HW structure
+ * @aq_err: the AQ error code to convert
+ **/
+char *i40e_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err)
+{
+ switch (aq_err) {
+ case I40E_AQ_RC_OK:
+ return "OK";
+ case I40E_AQ_RC_EPERM:
+ return "I40E_AQ_RC_EPERM";
+ case I40E_AQ_RC_ENOENT:
+ return "I40E_AQ_RC_ENOENT";
+ case I40E_AQ_RC_ESRCH:
+ return "I40E_AQ_RC_ESRCH";
+ case I40E_AQ_RC_EINTR:
+ return "I40E_AQ_RC_EINTR";
+ case I40E_AQ_RC_EIO:
+ return "I40E_AQ_RC_EIO";
+ case I40E_AQ_RC_ENXIO:
+ return "I40E_AQ_RC_ENXIO";
+ case I40E_AQ_RC_E2BIG:
+ return "I40E_AQ_RC_E2BIG";
+ case I40E_AQ_RC_EAGAIN:
+ return "I40E_AQ_RC_EAGAIN";
+ case I40E_AQ_RC_ENOMEM:
+ return "I40E_AQ_RC_ENOMEM";
+ case I40E_AQ_RC_EACCES:
+ return "I40E_AQ_RC_EACCES";
+ case I40E_AQ_RC_EFAULT:
+ return "I40E_AQ_RC_EFAULT";
+ case I40E_AQ_RC_EBUSY:
+ return "I40E_AQ_RC_EBUSY";
+ case I40E_AQ_RC_EEXIST:
+ return "I40E_AQ_RC_EEXIST";
+ case I40E_AQ_RC_EINVAL:
+ return "I40E_AQ_RC_EINVAL";
+ case I40E_AQ_RC_ENOTTY:
+ return "I40E_AQ_RC_ENOTTY";
+ case I40E_AQ_RC_ENOSPC:
+ return "I40E_AQ_RC_ENOSPC";
+ case I40E_AQ_RC_ENOSYS:
+ return "I40E_AQ_RC_ENOSYS";
+ case I40E_AQ_RC_ERANGE:
+ return "I40E_AQ_RC_ERANGE";
+ case I40E_AQ_RC_EFLUSHED:
+ return "I40E_AQ_RC_EFLUSHED";
+ case I40E_AQ_RC_BAD_ADDR:
+ return "I40E_AQ_RC_BAD_ADDR";
+ case I40E_AQ_RC_EMODE:
+ return "I40E_AQ_RC_EMODE";
+ case I40E_AQ_RC_EFBIG:
+ return "I40E_AQ_RC_EFBIG";
+ }
+
+ snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err);
+ return hw->err_str;
+}
+
+/**
+ * i40e_stat_str - convert status err code to a string
+ * @hw: pointer to the HW structure
+ * @stat_err: the status error code to convert
+ **/
+char *i40e_stat_str(struct i40e_hw *hw, enum i40e_status_code stat_err)
+{
+ switch (stat_err) {
+ case I40E_SUCCESS:
+ return "OK";
+ case I40E_ERR_NVM:
+ return "I40E_ERR_NVM";
+ case I40E_ERR_NVM_CHECKSUM:
+ return "I40E_ERR_NVM_CHECKSUM";
+ case I40E_ERR_PHY:
+ return "I40E_ERR_PHY";
+ case I40E_ERR_CONFIG:
+ return "I40E_ERR_CONFIG";
+ case I40E_ERR_PARAM:
+ return "I40E_ERR_PARAM";
+ case I40E_ERR_MAC_TYPE:
+ return "I40E_ERR_MAC_TYPE";
+ case I40E_ERR_UNKNOWN_PHY:
+ return "I40E_ERR_UNKNOWN_PHY";
+ case I40E_ERR_LINK_SETUP:
+ return "I40E_ERR_LINK_SETUP";
+ case I40E_ERR_ADAPTER_STOPPED:
+ return "I40E_ERR_ADAPTER_STOPPED";
+ case I40E_ERR_INVALID_MAC_ADDR:
+ return "I40E_ERR_INVALID_MAC_ADDR";
+ case I40E_ERR_DEVICE_NOT_SUPPORTED:
+ return "I40E_ERR_DEVICE_NOT_SUPPORTED";
+ case I40E_ERR_MASTER_REQUESTS_PENDING:
+ return "I40E_ERR_MASTER_REQUESTS_PENDING";
+ case I40E_ERR_INVALID_LINK_SETTINGS:
+ return "I40E_ERR_INVALID_LINK_SETTINGS";
+ case I40E_ERR_AUTONEG_NOT_COMPLETE:
+ return "I40E_ERR_AUTONEG_NOT_COMPLETE";
+ case I40E_ERR_RESET_FAILED:
+ return "I40E_ERR_RESET_FAILED";
+ case I40E_ERR_SWFW_SYNC:
+ return "I40E_ERR_SWFW_SYNC";
+ case I40E_ERR_NO_AVAILABLE_VSI:
+ return "I40E_ERR_NO_AVAILABLE_VSI";
+ case I40E_ERR_NO_MEMORY:
+ return "I40E_ERR_NO_MEMORY";
+ case I40E_ERR_BAD_PTR:
+ return "I40E_ERR_BAD_PTR";
+ case I40E_ERR_RING_FULL:
+ return "I40E_ERR_RING_FULL";
+ case I40E_ERR_INVALID_PD_ID:
+ return "I40E_ERR_INVALID_PD_ID";
+ case I40E_ERR_INVALID_QP_ID:
+ return "I40E_ERR_INVALID_QP_ID";
+ case I40E_ERR_INVALID_CQ_ID:
+ return "I40E_ERR_INVALID_CQ_ID";
+ case I40E_ERR_INVALID_CEQ_ID:
+ return "I40E_ERR_INVALID_CEQ_ID";
+ case I40E_ERR_INVALID_AEQ_ID:
+ return "I40E_ERR_INVALID_AEQ_ID";
+ case I40E_ERR_INVALID_SIZE:
+ return "I40E_ERR_INVALID_SIZE";
+ case I40E_ERR_INVALID_ARP_INDEX:
+ return "I40E_ERR_INVALID_ARP_INDEX";
+ case I40E_ERR_INVALID_FPM_FUNC_ID:
+ return "I40E_ERR_INVALID_FPM_FUNC_ID";
+ case I40E_ERR_QP_INVALID_MSG_SIZE:
+ return "I40E_ERR_QP_INVALID_MSG_SIZE";
+ case I40E_ERR_QP_TOOMANY_WRS_POSTED:
+ return "I40E_ERR_QP_TOOMANY_WRS_POSTED";
+ case I40E_ERR_INVALID_FRAG_COUNT:
+ return "I40E_ERR_INVALID_FRAG_COUNT";
+ case I40E_ERR_QUEUE_EMPTY:
+ return "I40E_ERR_QUEUE_EMPTY";
+ case I40E_ERR_INVALID_ALIGNMENT:
+ return "I40E_ERR_INVALID_ALIGNMENT";
+ case I40E_ERR_FLUSHED_QUEUE:
+ return "I40E_ERR_FLUSHED_QUEUE";
+ case I40E_ERR_INVALID_PUSH_PAGE_INDEX:
+ return "I40E_ERR_INVALID_PUSH_PAGE_INDEX";
+ case I40E_ERR_INVALID_IMM_DATA_SIZE:
+ return "I40E_ERR_INVALID_IMM_DATA_SIZE";
+ case I40E_ERR_TIMEOUT:
+ return "I40E_ERR_TIMEOUT";
+ case I40E_ERR_OPCODE_MISMATCH:
+ return "I40E_ERR_OPCODE_MISMATCH";
+ case I40E_ERR_CQP_COMPL_ERROR:
+ return "I40E_ERR_CQP_COMPL_ERROR";
+ case I40E_ERR_INVALID_VF_ID:
+ return "I40E_ERR_INVALID_VF_ID";
+ case I40E_ERR_INVALID_HMCFN_ID:
+ return "I40E_ERR_INVALID_HMCFN_ID";
+ case I40E_ERR_BACKING_PAGE_ERROR:
+ return "I40E_ERR_BACKING_PAGE_ERROR";
+ case I40E_ERR_NO_PBLCHUNKS_AVAILABLE:
+ return "I40E_ERR_NO_PBLCHUNKS_AVAILABLE";
+ case I40E_ERR_INVALID_PBLE_INDEX:
+ return "I40E_ERR_INVALID_PBLE_INDEX";
+ case I40E_ERR_INVALID_SD_INDEX:
+ return "I40E_ERR_INVALID_SD_INDEX";
+ case I40E_ERR_INVALID_PAGE_DESC_INDEX:
+ return "I40E_ERR_INVALID_PAGE_DESC_INDEX";
+ case I40E_ERR_INVALID_SD_TYPE:
+ return "I40E_ERR_INVALID_SD_TYPE";
+ case I40E_ERR_MEMCPY_FAILED:
+ return "I40E_ERR_MEMCPY_FAILED";
+ case I40E_ERR_INVALID_HMC_OBJ_INDEX:
+ return "I40E_ERR_INVALID_HMC_OBJ_INDEX";
+ case I40E_ERR_INVALID_HMC_OBJ_COUNT:
+ return "I40E_ERR_INVALID_HMC_OBJ_COUNT";
+ case I40E_ERR_INVALID_SRQ_ARM_LIMIT:
+ return "I40E_ERR_INVALID_SRQ_ARM_LIMIT";
+ case I40E_ERR_SRQ_ENABLED:
+ return "I40E_ERR_SRQ_ENABLED";
+ case I40E_ERR_ADMIN_QUEUE_ERROR:
+ return "I40E_ERR_ADMIN_QUEUE_ERROR";
+ case I40E_ERR_ADMIN_QUEUE_TIMEOUT:
+ return "I40E_ERR_ADMIN_QUEUE_TIMEOUT";
+ case I40E_ERR_BUF_TOO_SHORT:
+ return "I40E_ERR_BUF_TOO_SHORT";
+ case I40E_ERR_ADMIN_QUEUE_FULL:
+ return "I40E_ERR_ADMIN_QUEUE_FULL";
+ case I40E_ERR_ADMIN_QUEUE_NO_WORK:
+ return "I40E_ERR_ADMIN_QUEUE_NO_WORK";
+ case I40E_ERR_BAD_IWARP_CQE:
+ return "I40E_ERR_BAD_IWARP_CQE";
+ case I40E_ERR_NVM_BLANK_MODE:
+ return "I40E_ERR_NVM_BLANK_MODE";
+ case I40E_ERR_NOT_IMPLEMENTED:
+ return "I40E_ERR_NOT_IMPLEMENTED";
+ case I40E_ERR_PE_DOORBELL_NOT_ENABLED:
+ return "I40E_ERR_PE_DOORBELL_NOT_ENABLED";
+ case I40E_ERR_DIAG_TEST_FAILED:
+ return "I40E_ERR_DIAG_TEST_FAILED";
+ case I40E_ERR_NOT_READY:
+ return "I40E_ERR_NOT_READY";
+ case I40E_NOT_SUPPORTED:
+ return "I40E_NOT_SUPPORTED";
+ case I40E_ERR_FIRMWARE_API_VERSION:
+ return "I40E_ERR_FIRMWARE_API_VERSION";
+ }
+
+ snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
+ return hw->err_str;
+}
+
+/**
* i40e_debug_aq
* @hw: debug mask related to admin queue
* @mask: debug mask
@@ -154,9 +375,13 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
bool i40e_check_asq_alive(struct i40e_hw *hw)
{
if (hw->aq.asq.len)
- return !!(rd32(hw, hw->aq.asq.len) & I40E_PF_ATQLEN_ATQENABLE_MASK);
- else
- return FALSE;
+ if (!i40e_is_vf(hw))
+ return !!(rd32(hw, hw->aq.asq.len) &
+ I40E_PF_ATQLEN_ATQENABLE_MASK);
+ if (i40e_is_vf(hw))
+ return !!(rd32(hw, hw->aq.asq.len) &
+ I40E_VF_ATQLEN1_ATQENABLE_MASK);
+ return FALSE;
}
/**
@@ -184,6 +409,171 @@ enum i40e_status_code i40e_aq_queue_shutdown(struct i40e_hw *hw,
return status;
}
+#ifdef X722_SUPPORT
+
+/**
+ * i40e_aq_get_set_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set TRUE, for VSI table set FALSE
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ * @set: set TRUE to set the table, FALSE to get the table
+ *
+ * Internal function to get or set RSS look up table
+ **/
+static enum i40e_status_code i40e_aq_get_set_rss_lut(struct i40e_hw *hw,
+ u16 vsi_id, bool pf_lut,
+ u8 *lut, u16 lut_size,
+ bool set)
+{
+ enum i40e_status_code status;
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_set_rss_lut *cmd_resp =
+ (struct i40e_aqc_get_set_rss_lut *)&desc.params.raw;
+
+ if (set)
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_rss_lut);
+ else
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_get_rss_lut);
+
+ /* Indirect command */
+ desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+ desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
+
+ cmd_resp->vsi_id =
+ CPU_TO_LE16((u16)((vsi_id <<
+ I40E_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
+ I40E_AQC_SET_RSS_LUT_VSI_ID_MASK));
+ cmd_resp->vsi_id |= CPU_TO_LE16((u16)I40E_AQC_SET_RSS_LUT_VSI_VALID);
+
+ if (pf_lut)
+ cmd_resp->flags |= CPU_TO_LE16((u16)
+ ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
+ I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
+ I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
+ else
+ cmd_resp->flags |= CPU_TO_LE16((u16)
+ ((I40E_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
+ I40E_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
+ I40E_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
+
+ cmd_resp->addr_high = CPU_TO_LE32(I40E_HI_WORD((u64)lut));
+ cmd_resp->addr_low = CPU_TO_LE32(I40E_LO_DWORD((u64)lut));
+
+ status = i40e_asq_send_command(hw, &desc, lut, lut_size, NULL);
+
+ return status;
+}
+
+/**
+ * i40e_aq_get_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set TRUE, for VSI table set FALSE
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ *
+ * get the RSS lookup table, PF or VSI type
+ **/
+enum i40e_status_code i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 vsi_id,
+ bool pf_lut, u8 *lut, u16 lut_size)
+{
+ return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
+ FALSE);
+}
+
+/**
+ * i40e_aq_set_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set TRUE, for VSI table set FALSE
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ *
+ * set the RSS lookup table, PF or VSI type
+ **/
+enum i40e_status_code i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 vsi_id,
+ bool pf_lut, u8 *lut, u16 lut_size)
+{
+ return i40e_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, TRUE);
+}
+
+/**
+ * i40e_aq_get_set_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ * @set: set TRUE to set the key, FALSE to get the key
+ *
+ * get the RSS key per VSI
+ **/
+static enum i40e_status_code i40e_aq_get_set_rss_key(struct i40e_hw *hw,
+ u16 vsi_id,
+ struct i40e_aqc_get_set_rss_key_data *key,
+ bool set)
+{
+ enum i40e_status_code status;
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_get_set_rss_key *cmd_resp =
+ (struct i40e_aqc_get_set_rss_key *)&desc.params.raw;
+ u16 key_size = sizeof(struct i40e_aqc_get_set_rss_key_data);
+
+ if (set)
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_rss_key);
+ else
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_get_rss_key);
+
+ /* Indirect command */
+ desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+ desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_RD);
+
+ cmd_resp->vsi_id =
+ CPU_TO_LE16((u16)((vsi_id <<
+ I40E_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
+ I40E_AQC_SET_RSS_KEY_VSI_ID_MASK));
+ cmd_resp->vsi_id |= CPU_TO_LE16((u16)I40E_AQC_SET_RSS_KEY_VSI_VALID);
+ cmd_resp->addr_high = CPU_TO_LE32(I40E_HI_WORD((u64)key));
+ cmd_resp->addr_low = CPU_TO_LE32(I40E_LO_DWORD((u64)key));
+
+ status = i40e_asq_send_command(hw, &desc, key, key_size, NULL);
+
+ return status;
+}
+
+/**
+ * i40e_aq_get_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ *
+ **/
+enum i40e_status_code i40e_aq_get_rss_key(struct i40e_hw *hw,
+ u16 vsi_id,
+ struct i40e_aqc_get_set_rss_key_data *key)
+{
+ return i40e_aq_get_set_rss_key(hw, vsi_id, key, FALSE);
+}
+
+/**
+ * i40e_aq_set_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ *
+ * set the RSS key per VSI
+ **/
+enum i40e_status_code i40e_aq_set_rss_key(struct i40e_hw *hw,
+ u16 vsi_id,
+ struct i40e_aqc_get_set_rss_key_data *key)
+{
+ return i40e_aq_get_set_rss_key(hw, vsi_id, key, TRUE);
+}
+#endif /* X722_SUPPORT */
/* The i40e_ptype_lookup table is used to convert from the 8-bit ptype in the
* hardware to a bit-field that can be used by SW to more easily determine the
@@ -598,6 +988,9 @@ enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw)
switch (hw->mac.type) {
case I40E_MAC_XL710:
+#ifdef X722_SUPPORT
+ case I40E_MAC_X722:
+#endif
break;
default:
return I40E_ERR_DEVICE_NOT_SUPPORTED;
@@ -888,7 +1281,7 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
grst_del = (rd32(hw, I40E_GLGEN_RSTCTL) &
I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
- for (cnt = 0; cnt < grst_del + 2; cnt++) {
+ for (cnt = 0; cnt < grst_del + 10; cnt++) {
reg = rd32(hw, I40E_GLGEN_RSTAT);
if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
break;
@@ -1108,9 +1501,11 @@ u32 i40e_led_get(struct i40e_hw *hw)
if (!gpio_val)
continue;
- /* ignore gpio LED src mode entries related to the activity LEDs */
- current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>
- I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
+ /* ignore gpio LED src mode entries related to the activity
+ * LEDs
+ */
+ current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK)
+ >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
switch (current_mode) {
case I40E_COMBINED_ACTIVITY:
case I40E_FILTER_ACTIVITY:
@@ -1154,9 +1549,11 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
if (!gpio_val)
continue;
- /* ignore gpio LED src mode entries related to the activity LEDs */
- current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK) >>
- I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
+ /* ignore gpio LED src mode entries related to the activity
+ * LEDs
+ */
+ current_mode = ((gpio_val & I40E_GLGEN_GPIO_CTL_LED_MODE_MASK)
+ >> I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT);
switch (current_mode) {
case I40E_COMBINED_ACTIVITY:
case I40E_FILTER_ACTIVITY:
@@ -1175,9 +1572,9 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
blink = FALSE;
if (blink)
- gpio_val |= (1 << I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
+ gpio_val |= BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
else
- gpio_val &= ~(1 << I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
+ gpio_val &= ~BIT(I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT);
wr32(hw, I40E_GLGEN_GPIO_CTL(i), gpio_val);
break;
@@ -1329,14 +1726,14 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
*aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
}
/* Update the link info */
- status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
+ status = i40e_update_link_info(hw);
if (status) {
/* Wait a little bit (on 40G cards it sometimes takes a really
* long time for link to come back from the atomic reset)
* and try once more
*/
i40e_msec_delay(1000);
- status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
+ status = i40e_update_link_info(hw);
}
if (status)
*aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
@@ -1525,7 +1922,6 @@ aq_get_link_info_exit:
return status;
}
-
/**
* i40e_aq_set_phy_int_mask
* @hw: pointer to the hw struct
@@ -1837,6 +2233,74 @@ enum i40e_status_code i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
}
/**
+ * i40e_aq_set_vsi_mc_promisc_on_vlan
+ * @hw: pointer to the hw struct
+ * @seid: vsi number
+ * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
+ * @vid: The VLAN tag filter - capture any multicast packet with this VLAN tag
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
+ u16 seid, bool enable, u16 vid,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+ enum i40e_status_code status;
+ u16 flags = 0;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+
+ if (enable)
+ flags |= I40E_AQC_SET_VSI_PROMISC_MULTICAST;
+
+ cmd->promiscuous_flags = CPU_TO_LE16(flags);
+ cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_MULTICAST);
+ cmd->seid = CPU_TO_LE16(seid);
+ cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
+
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
+ * i40e_aq_set_vsi_uc_promisc_on_vlan
+ * @hw: pointer to the hw struct
+ * @seid: vsi number
+ * @enable: set MAC L2 layer unicast promiscuous enable/disable for a given VLAN
+ * @vid: The VLAN tag filter - capture any unicast packet with this VLAN tag
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
+ u16 seid, bool enable, u16 vid,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_set_vsi_promiscuous_modes *cmd =
+ (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw;
+ enum i40e_status_code status;
+ u16 flags = 0;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_set_vsi_promiscuous_modes);
+
+ if (enable)
+ flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
+
+ cmd->promiscuous_flags = CPU_TO_LE16(flags);
+ cmd->valid_flags = CPU_TO_LE16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
+ cmd->seid = CPU_TO_LE16(seid);
+ cmd->vlan_tag = CPU_TO_LE16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
+
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
* i40e_aq_set_vsi_broadcast
* @hw: pointer to the hw struct
* @seid: vsi number
@@ -2067,30 +2531,56 @@ enum i40e_status_code i40e_aq_send_driver_version(struct i40e_hw *hw,
/**
* i40e_get_link_status - get status of the HW network link
* @hw: pointer to the hw struct
+ * @link_up: pointer to bool (TRUE/FALSE = linkup/linkdown)
*
- * Returns TRUE if link is up, FALSE if link is down.
+ * Variable link_up TRUE if link is up, FALSE if link is down.
+ * The variable link_up is invalid if returned value of status != I40E_SUCCESS
*
* Side effect: LinkStatusEvent reporting becomes enabled
**/
-bool i40e_get_link_status(struct i40e_hw *hw)
+enum i40e_status_code i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
{
enum i40e_status_code status = I40E_SUCCESS;
- bool link_status = FALSE;
if (hw->phy.get_link_info) {
- status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
+ status = i40e_update_link_info(hw);
if (status != I40E_SUCCESS)
- goto i40e_get_link_status_exit;
+ i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n",
+ status);
}
- link_status = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
+ *link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
-i40e_get_link_status_exit:
- return link_status;
+ return status;
}
/**
+ * i40e_updatelink_status - update status of the HW network link
+ * @hw: pointer to the hw struct
+ **/
+enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw)
+{
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ enum i40e_status_code status = I40E_SUCCESS;
+
+ status = i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
+ if (status)
+ return status;
+
+ status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
+ NULL);
+ if (status)
+ return status;
+
+ memcpy(hw->phy.link_info.module_type, &abilities.module_type,
+ sizeof(hw->phy.link_info.module_type));
+
+ return status;
+}
+
+
+/**
* i40e_get_link_speed
* @hw: pointer to the hw struct
*
@@ -2218,6 +2708,7 @@ enum i40e_status_code i40e_aq_get_veb_parameters(struct i40e_hw *hw,
*vebs_free = LE16_TO_CPU(cmd_resp->vebs_free);
if (floating) {
u16 flags = LE16_TO_CPU(cmd_resp->veb_flags);
+
if (flags & I40E_AQC_ADD_VEB_FLOATING)
*floating = TRUE;
else
@@ -2750,6 +3241,27 @@ enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw,
}
/**
+ * i40e_aq_oem_post_update - triggers an OEM specific flow after update
+ * @hw: pointer to the hw struct
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum i40e_status_code i40e_aq_oem_post_update(struct i40e_hw *hw,
+ void *buff, u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ enum i40e_status_code status;
+
+
+ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_oem_post_update);
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+ if (status && LE16_TO_CPU(desc.retval) == I40E_AQ_RC_ESRCH)
+ status = I40E_ERR_NOT_IMPLEMENTED;
+
+ return status;
+}
+
+/**
* i40e_aq_erase_nvm
* @hw: pointer to the hw struct
* @module_pointer: module pointer location in words from the NVM beginning
@@ -2813,12 +3325,13 @@ i40e_aq_erase_nvm_exit:
#define I40E_DEV_FUNC_CAP_MSIX_VF 0x44
#define I40E_DEV_FUNC_CAP_FLOW_DIRECTOR 0x45
#define I40E_DEV_FUNC_CAP_IEEE_1588 0x46
-#define I40E_DEV_FUNC_CAP_MFP_MODE_1 0xF1
+#define I40E_DEV_FUNC_CAP_FLEX10 0xF1
#define I40E_DEV_FUNC_CAP_CEM 0xF2
#define I40E_DEV_FUNC_CAP_IWARP 0x51
#define I40E_DEV_FUNC_CAP_LED 0x61
#define I40E_DEV_FUNC_CAP_SDP 0x62
#define I40E_DEV_FUNC_CAP_MDIO 0x63
+#define I40E_DEV_FUNC_CAP_WR_CSR_PROT 0x64
/**
* i40e_parse_discover_capabilities
@@ -2837,6 +3350,7 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
u32 valid_functions, num_functions;
u32 number, logical_id, phys_id;
struct i40e_hw_capabilities *p;
+ u8 major_rev;
u32 i = 0;
u16 id;
@@ -2854,6 +3368,7 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
number = LE32_TO_CPU(cap->number);
logical_id = LE32_TO_CPU(cap->logical_id);
phys_id = LE32_TO_CPU(cap->phys_id);
+ major_rev = cap->major_rev;
switch (id) {
case I40E_DEV_FUNC_CAP_SWITCH_MODE:
@@ -2928,9 +3443,21 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
case I40E_DEV_FUNC_CAP_MSIX_VF:
p->num_msix_vectors_vf = number;
break;
- case I40E_DEV_FUNC_CAP_MFP_MODE_1:
- if (number == 1)
- p->mfp_mode_1 = TRUE;
+ case I40E_DEV_FUNC_CAP_FLEX10:
+ if (major_rev == 1) {
+ if (number == 1) {
+ p->flex10_enable = TRUE;
+ p->flex10_capable = TRUE;
+ }
+ } else {
+ /* Capability revision >= 2 */
+ if (number & 1)
+ p->flex10_enable = TRUE;
+ if (number & 2)
+ p->flex10_capable = TRUE;
+ }
+ p->flex10_mode = logical_id;
+ p->flex10_status = phys_id;
break;
case I40E_DEV_FUNC_CAP_CEM:
if (number == 1)
@@ -2963,11 +3490,18 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
p->fd_filters_guaranteed = number;
p->fd_filters_best_effort = logical_id;
break;
+ case I40E_DEV_FUNC_CAP_WR_CSR_PROT:
+ p->wr_csr_prot = (u64)number;
+ p->wr_csr_prot |= (u64)logical_id << 32;
+ break;
default:
break;
}
}
+ if (p->fcoe)
+ i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");
+
/* Always disable FCoE if compiled without the I40E_FCOE_ENA flag */
p->fcoe = FALSE;
@@ -4923,6 +5457,63 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
}
/**
+ * i40e_aq_debug_dump
+ * @hw: pointer to the hardware structure
+ * @cluster_id: specific cluster to dump
+ * @table_id: table id within cluster
+ * @start_index: index of line in the block to read
+ * @buff_size: dump buffer size
+ * @buff: dump buffer
+ * @ret_buff_size: actual buffer size returned
+ * @ret_next_table: next block to read
+ * @ret_next_index: next index to read
+ *
+ * Dump internal FW/HW data for debug purposes.
+ *
+ **/
+enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
+ u8 table_id, u32 start_index, u16 buff_size,
+ void *buff, u16 *ret_buff_size,
+ u8 *ret_next_table, u32 *ret_next_index,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_debug_dump_internals *cmd =
+ (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
+ struct i40e_aqc_debug_dump_internals *resp =
+ (struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
+ enum i40e_status_code status;
+
+ if (buff_size == 0 || !buff)
+ return I40E_ERR_PARAM;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_debug_dump_internals);
+ /* Indirect Command */
+ desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_BUF);
+ if (buff_size > I40E_AQ_LARGE_BUF)
+ desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB);
+
+ cmd->cluster_id = cluster_id;
+ cmd->table_id = table_id;
+ cmd->idx = CPU_TO_LE32(start_index);
+
+ desc.datalen = CPU_TO_LE16(buff_size);
+
+ status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+ if (!status) {
+ if (ret_buff_size != NULL)
+ *ret_buff_size = LE16_TO_CPU(desc.datalen);
+ if (ret_next_table != NULL)
+ *ret_next_table = resp->table_id;
+ if (ret_next_index != NULL)
+ *ret_next_index = LE32_TO_CPU(resp->idx);
+ }
+
+ return status;
+}
+
+/**
* i40e_read_bw_from_alt_ram
* @hw: pointer to the hardware structure
* @max_bw: pointer for max_bw read
@@ -4941,11 +5532,11 @@ enum i40e_status_code i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
/* Calculate the address of the min/max bw registers */
max_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
- I40E_ALT_STRUCT_MAX_BW_OFFSET +
- (I40E_ALT_STRUCT_DWORDS_PER_PF*hw->pf_id);
+ I40E_ALT_STRUCT_MAX_BW_OFFSET +
+ (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
min_bw_addr = I40E_ALT_STRUCT_FIRST_PF_OFFSET +
- I40E_ALT_STRUCT_MIN_BW_OFFSET +
- (I40E_ALT_STRUCT_DWORDS_PER_PF*hw->pf_id);
+ I40E_ALT_STRUCT_MIN_BW_OFFSET +
+ (I40E_ALT_STRUCT_DWORDS_PER_PF * hw->pf_id);
/* Read the bandwidths from alt ram */
status = i40e_aq_alternate_read(hw, max_bw_addr, max_bw,
diff --git a/sys/dev/ixl/i40e_devids.h b/sys/dev/ixl/i40e_devids.h
new file mode 100644
index 000000000000..abd597a9ead2
--- /dev/null
+++ b/sys/dev/ixl/i40e_devids.h
@@ -0,0 +1,68 @@
+/******************************************************************************
+
+ Copyright (c) 2013-2015, Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel 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.
+
+******************************************************************************/
+/*$FreeBSD$*/
+
+#ifndef _I40E_DEVIDS_H_
+#define _I40E_DEVIDS_H_
+
+/* Vendor ID */
+#define I40E_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define I40E_DEV_ID_SFP_XL710 0x1572
+#define I40E_DEV_ID_QEMU 0x1574
+#define I40E_DEV_ID_KX_A 0x157F
+#define I40E_DEV_ID_KX_B 0x1580
+#define I40E_DEV_ID_KX_C 0x1581
+#define I40E_DEV_ID_QSFP_A 0x1583
+#define I40E_DEV_ID_QSFP_B 0x1584
+#define I40E_DEV_ID_QSFP_C 0x1585
+#define I40E_DEV_ID_10G_BASE_T 0x1586
+#define I40E_DEV_ID_20G_KR2 0x1587
+#define I40E_DEV_ID_20G_KR2_A 0x1588
+#define I40E_DEV_ID_10G_BASE_T4 0x1589
+#define I40E_DEV_ID_VF 0x154C
+#define I40E_DEV_ID_VF_HV 0x1571
+#ifdef X722_SUPPORT
+#define I40E_DEV_ID_SFP_X722 0x37D0
+#define I40E_DEV_ID_1G_BASE_T_X722 0x37D1
+#define I40E_DEV_ID_10G_BASE_T_X722 0x37D2
+#define I40E_DEV_ID_X722_VF 0x37CD
+#define I40E_DEV_ID_X722_VF_HV 0x37D9
+#endif /* X722_SUPPORT */
+
+#define i40e_is_40G_device(d) ((d) == I40E_DEV_ID_QSFP_A || \
+ (d) == I40E_DEV_ID_QSFP_B || \
+ (d) == I40E_DEV_ID_QSFP_C)
+
+#endif /* _I40E_DEVIDS_H_ */
diff --git a/sys/dev/ixl/i40e_hmc.c b/sys/dev/ixl/i40e_hmc.c
index 81cb2ae99606..513f1d572f7c 100644
--- a/sys/dev/ixl/i40e_hmc.c
+++ b/sys/dev/ixl/i40e_hmc.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2013-2014, Intel Corporation
+ Copyright (c) 2013-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -130,6 +130,7 @@ exit:
* @hw: pointer to our HW structure
* @hmc_info: pointer to the HMC configuration information structure
* @pd_index: which page descriptor index to manipulate
+ * @rsrc_pg: if not NULL, use preallocated page instead of allocating new one.
*
* This function:
* 1. Initializes the pd entry
@@ -143,12 +144,14 @@ exit:
**/
enum i40e_status_code i40e_add_pd_table_entry(struct i40e_hw *hw,
struct i40e_hmc_info *hmc_info,
- u32 pd_index)
+ u32 pd_index,
+ struct i40e_dma_mem *rsrc_pg)
{
enum i40e_status_code ret_code = I40E_SUCCESS;
struct i40e_hmc_pd_table *pd_table;
struct i40e_hmc_pd_entry *pd_entry;
struct i40e_dma_mem mem;
+ struct i40e_dma_mem *page = &mem;
u32 sd_idx, rel_pd_idx;
u64 *pd_addr;
u64 page_desc;
@@ -169,19 +172,25 @@ enum i40e_status_code i40e_add_pd_table_entry(struct i40e_hw *hw,
pd_table = &hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
pd_entry = &pd_table->pd_entry[rel_pd_idx];
if (!pd_entry->valid) {
- /* allocate a 4K backing page */
- ret_code = i40e_allocate_dma_mem(hw, &mem, i40e_mem_bp,
- I40E_HMC_PAGED_BP_SIZE,
- I40E_HMC_PD_BP_BUF_ALIGNMENT);
- if (ret_code)
- goto exit;
+ if (rsrc_pg) {
+ pd_entry->rsrc_pg = TRUE;
+ page = rsrc_pg;
+ } else {
+ /* allocate a 4K backing page */
+ ret_code = i40e_allocate_dma_mem(hw, page, i40e_mem_bp,
+ I40E_HMC_PAGED_BP_SIZE,
+ I40E_HMC_PD_BP_BUF_ALIGNMENT);
+ if (ret_code)
+ goto exit;
+ pd_entry->rsrc_pg = FALSE;
+ }
- i40e_memcpy(&pd_entry->bp.addr, &mem,
+ i40e_memcpy(&pd_entry->bp.addr, page,
sizeof(struct i40e_dma_mem), I40E_NONDMA_TO_NONDMA);
pd_entry->bp.sd_pd_index = pd_index;
pd_entry->bp.entry_type = I40E_SD_TYPE_PAGED;
/* Set page address and valid bit */
- page_desc = mem.pa | 0x1;
+ page_desc = page->pa | 0x1;
pd_addr = (u64 *)pd_table->pd_page_addr.va;
pd_addr += rel_pd_idx;
@@ -256,7 +265,8 @@ enum i40e_status_code i40e_remove_pd_bp(struct i40e_hw *hw,
I40E_INVALIDATE_PF_HMC_PD(hw, sd_idx, idx);
/* free memory here */
- ret_code = i40e_free_dma_mem(hw, &(pd_entry->bp.addr));
+ if (!pd_entry->rsrc_pg)
+ ret_code = i40e_free_dma_mem(hw, &(pd_entry->bp.addr));
if (I40E_SUCCESS != ret_code)
goto exit;
if (!pd_table->ref_cnt)
@@ -303,21 +313,15 @@ enum i40e_status_code i40e_remove_sd_bp_new(struct i40e_hw *hw,
u32 idx, bool is_pf)
{
struct i40e_hmc_sd_entry *sd_entry;
- enum i40e_status_code ret_code = I40E_SUCCESS;
+
+ if (!is_pf)
+ return I40E_NOT_SUPPORTED;
/* get the entry and decrease its ref counter */
sd_entry = &hmc_info->sd_table.sd_entry[idx];
- if (is_pf) {
- I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_DIRECT);
- } else {
- ret_code = I40E_NOT_SUPPORTED;
- goto exit;
- }
- ret_code = i40e_free_dma_mem(hw, &(sd_entry->u.bp.addr));
- if (I40E_SUCCESS != ret_code)
- goto exit;
-exit:
- return ret_code;
+ I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_DIRECT);
+
+ return i40e_free_dma_mem(hw, &(sd_entry->u.bp.addr));
}
/**
@@ -357,20 +361,13 @@ enum i40e_status_code i40e_remove_pd_page_new(struct i40e_hw *hw,
struct i40e_hmc_info *hmc_info,
u32 idx, bool is_pf)
{
- enum i40e_status_code ret_code = I40E_SUCCESS;
struct i40e_hmc_sd_entry *sd_entry;
+ if (!is_pf)
+ return I40E_NOT_SUPPORTED;
+
sd_entry = &hmc_info->sd_table.sd_entry[idx];
- if (is_pf) {
- I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_PAGED);
- } else {
- ret_code = I40E_NOT_SUPPORTED;
- goto exit;
- }
- /* free memory here */
- ret_code = i40e_free_dma_mem(hw, &(sd_entry->u.pd_table.pd_page_addr));
- if (I40E_SUCCESS != ret_code)
- goto exit;
-exit:
- return ret_code;
+ I40E_CLEAR_PF_SD_ENTRY(hw, idx, I40E_SD_TYPE_PAGED);
+
+ return i40e_free_dma_mem(hw, &(sd_entry->u.pd_table.pd_page_addr));
}
diff --git a/sys/dev/ixl/i40e_hmc.h b/sys/dev/ixl/i40e_hmc.h
index cba325f5a8b9..1a9995ab6afc 100644
--- a/sys/dev/ixl/i40e_hmc.h
+++ b/sys/dev/ixl/i40e_hmc.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2013-2014, Intel Corporation
+ Copyright (c) 2013-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -70,6 +70,7 @@ struct i40e_hmc_bp {
struct i40e_hmc_pd_entry {
struct i40e_hmc_bp bp;
u32 sd_index;
+ bool rsrc_pg;
bool valid;
};
@@ -134,8 +135,8 @@ struct i40e_hmc_info {
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \
((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \
I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT) | \
- (1 << I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT); \
- val3 = (sd_index) | (1u << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
+ BIT(I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT); \
+ val3 = (sd_index) | BIT_ULL(I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
wr32((hw), I40E_PFHMC_SDDATAHIGH, val1); \
wr32((hw), I40E_PFHMC_SDDATALOW, val2); \
wr32((hw), I40E_PFHMC_SDCMD, val3); \
@@ -154,7 +155,7 @@ struct i40e_hmc_info {
I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \
((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \
I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT); \
- val3 = (sd_index) | (1u << I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
+ val3 = (sd_index) | BIT_ULL(I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \
wr32((hw), I40E_PFHMC_SDDATAHIGH, 0); \
wr32((hw), I40E_PFHMC_SDDATALOW, val2); \
wr32((hw), I40E_PFHMC_SDCMD, val3); \
@@ -226,7 +227,8 @@ enum i40e_status_code i40e_add_sd_table_entry(struct i40e_hw *hw,
enum i40e_status_code i40e_add_pd_table_entry(struct i40e_hw *hw,
struct i40e_hmc_info *hmc_info,
- u32 pd_index);
+ u32 pd_index,
+ struct i40e_dma_mem *rsrc_pg);
enum i40e_status_code i40e_remove_pd_bp(struct i40e_hw *hw,
struct i40e_hmc_info *hmc_info,
u32 idx);
diff --git a/sys/dev/ixl/i40e_lan_hmc.c b/sys/dev/ixl/i40e_lan_hmc.c
index 0866ad14851c..f6c951468c4b 100644
--- a/sys/dev/ixl/i40e_lan_hmc.c
+++ b/sys/dev/ixl/i40e_lan_hmc.c
@@ -137,7 +137,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
obj->cnt = txq_num;
obj->base = 0;
size_exp = rd32(hw, I40E_GLHMC_LANTXOBJSZ);
- obj->size = (u64)1 << size_exp;
+ obj->size = BIT_ULL(size_exp);
/* validate values requested by driver don't exceed HMC capacity */
if (txq_num > obj->max_cnt) {
@@ -160,7 +160,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
hw->hmc.hmc_obj[I40E_HMC_LAN_TX].size);
obj->base = i40e_align_l2obj_base(obj->base);
size_exp = rd32(hw, I40E_GLHMC_LANRXOBJSZ);
- obj->size = (u64)1 << size_exp;
+ obj->size = BIT_ULL(size_exp);
/* validate values requested by driver don't exceed HMC capacity */
if (rxq_num > obj->max_cnt) {
@@ -183,7 +183,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
hw->hmc.hmc_obj[I40E_HMC_LAN_RX].size);
obj->base = i40e_align_l2obj_base(obj->base);
size_exp = rd32(hw, I40E_GLHMC_FCOEDDPOBJSZ);
- obj->size = (u64)1 << size_exp;
+ obj->size = BIT_ULL(size_exp);
/* validate values requested by driver don't exceed HMC capacity */
if (fcoe_cntx_num > obj->max_cnt) {
@@ -206,7 +206,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].size);
obj->base = i40e_align_l2obj_base(obj->base);
size_exp = rd32(hw, I40E_GLHMC_FCOEFOBJSZ);
- obj->size = (u64)1 << size_exp;
+ obj->size = BIT_ULL(size_exp);
/* validate values requested by driver don't exceed HMC capacity */
if (fcoe_filt_num > obj->max_cnt) {
@@ -395,7 +395,7 @@ enum i40e_status_code i40e_create_lan_hmc_object(struct i40e_hw *hw,
/* update the pd table entry */
ret_code = i40e_add_pd_table_entry(hw,
info->hmc_info,
- i);
+ i, NULL);
if (I40E_SUCCESS != ret_code) {
pd_error = TRUE;
break;
@@ -439,9 +439,8 @@ exit_sd_error:
pd_idx1 = max(pd_idx,
((j - 1) * I40E_HMC_MAX_BP_COUNT));
pd_lmt1 = min(pd_lmt, (j * I40E_HMC_MAX_BP_COUNT));
- for (i = pd_idx1; i < pd_lmt1; i++) {
+ for (i = pd_idx1; i < pd_lmt1; i++)
i40e_remove_pd_bp(hw, info->hmc_info, i);
- }
i40e_remove_pd_page(hw, info->hmc_info, (j - 1));
break;
case I40E_SD_TYPE_DIRECT:
@@ -771,7 +770,7 @@ static void i40e_write_byte(u8 *hmc_bits,
/* prepare the bits and mask */
shift_width = ce_info->lsb % 8;
- mask = ((u8)1 << ce_info->width) - 1;
+ mask = BIT(ce_info->width) - 1;
src_byte = *from;
src_byte &= mask;
@@ -812,7 +811,7 @@ static void i40e_write_word(u8 *hmc_bits,
/* prepare the bits and mask */
shift_width = ce_info->lsb % 8;
- mask = ((u16)1 << ce_info->width) - 1;
+ mask = BIT(ce_info->width) - 1;
/* don't swizzle the bits until after the mask because the mask bits
* will be in a different bit position on big endian machines
@@ -862,7 +861,7 @@ static void i40e_write_dword(u8 *hmc_bits,
* to 5 bits so the shift will do nothing
*/
if (ce_info->width < 32)
- mask = ((u32)1 << ce_info->width) - 1;
+ mask = BIT(ce_info->width) - 1;
else
mask = ~(u32)0;
@@ -914,7 +913,7 @@ static void i40e_write_qword(u8 *hmc_bits,
* to 6 bits so the shift will do nothing
*/
if (ce_info->width < 64)
- mask = ((u64)1 << ce_info->width) - 1;
+ mask = BIT_ULL(ce_info->width) - 1;
else
mask = ~(u64)0;
@@ -956,7 +955,7 @@ static void i40e_read_byte(u8 *hmc_bits,
/* prepare the bits and mask */
shift_width = ce_info->lsb % 8;
- mask = ((u8)1 << ce_info->width) - 1;
+ mask = BIT(ce_info->width) - 1;
/* shift to correct alignment */
mask <<= shift_width;
@@ -994,7 +993,7 @@ static void i40e_read_word(u8 *hmc_bits,
/* prepare the bits and mask */
shift_width = ce_info->lsb % 8;
- mask = ((u16)1 << ce_info->width) - 1;
+ mask = BIT(ce_info->width) - 1;
/* shift to correct alignment */
mask <<= shift_width;
@@ -1044,7 +1043,7 @@ static void i40e_read_dword(u8 *hmc_bits,
* to 5 bits so the shift will do nothing
*/
if (ce_info->width < 32)
- mask = ((u32)1 << ce_info->width) - 1;
+ mask = BIT(ce_info->width) - 1;
else
mask = ~(u32)0;
@@ -1097,7 +1096,7 @@ static void i40e_read_qword(u8 *hmc_bits,
* to 6 bits so the shift will do nothing
*/
if (ce_info->width < 64)
- mask = ((u64)1 << ce_info->width) - 1;
+ mask = BIT_ULL(ce_info->width) - 1;
else
mask = ~(u64)0;
diff --git a/sys/dev/ixl/i40e_nvm.c b/sys/dev/ixl/i40e_nvm.c
index 35001a58e4e4..5ae7515e4236 100644
--- a/sys/dev/ixl/i40e_nvm.c
+++ b/sys/dev/ixl/i40e_nvm.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2013-2014, Intel Corporation
+ Copyright (c) 2013-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -72,7 +72,7 @@ enum i40e_status_code i40e_init_nvm(struct i40e_hw *hw)
sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >>
I40E_GLNVM_GENS_SR_SIZE_SHIFT);
/* Switching to words (sr_size contains power of 2KB) */
- nvm->sr_size = (1 << sr_size) * I40E_SR_WORDS_IN_1KB;
+ nvm->sr_size = BIT(sr_size) * I40E_SR_WORDS_IN_1KB;
/* Check if we are in the normal or blank NVM programming mode */
fla = rd32(hw, I40E_GLNVM_FLA);
@@ -158,10 +158,26 @@ i40e_i40e_acquire_nvm_exit:
**/
void i40e_release_nvm(struct i40e_hw *hw)
{
+ enum i40e_status_code ret_code = I40E_SUCCESS;
+ u32 total_delay = 0;
+
DEBUGFUNC("i40e_release_nvm");
- if (!hw->nvm.blank_nvm_mode)
- i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
+ if (hw->nvm.blank_nvm_mode)
+ return;
+
+ ret_code = i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
+
+ /* there are some rare cases when trying to release the resource
+ * results in an admin Q timeout, so handle them correctly
+ */
+ while ((ret_code == I40E_ERR_ADMIN_QUEUE_TIMEOUT) &&
+ (total_delay < hw->aq.asq_cmd_timeout)) {
+ i40e_msec_delay(1);
+ ret_code = i40e_aq_release_resource(hw,
+ I40E_NVM_RESOURCE_ID, 0, NULL);
+ total_delay++;
+ }
}
/**
@@ -202,6 +218,10 @@ static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
u16 *data)
{
+#ifdef X722_SUPPORT
+ if (hw->mac.type == I40E_MAC_X722)
+ return i40e_read_nvm_word_aq(hw, offset, data);
+#endif
return i40e_read_nvm_word_srctl(hw, offset, data);
}
@@ -233,8 +253,8 @@ enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
ret_code = i40e_poll_sr_srctl_done_bit(hw);
if (ret_code == I40E_SUCCESS) {
/* Write the address and start reading */
- sr_reg = (u32)(offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
- (1 << I40E_GLNVM_SRCTL_START_SHIFT);
+ sr_reg = ((u32)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
+ BIT(I40E_GLNVM_SRCTL_START_SHIFT);
wr32(hw, I40E_GLNVM_SRCTL, sr_reg);
/* Poll I40E_GLNVM_SRCTL until the done bit is set */
@@ -290,6 +310,10 @@ enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
u16 *words, u16 *data)
{
+#ifdef X722_SUPPORT
+ if (hw->mac.type == I40E_MAC_X722)
+ return i40e_read_nvm_buffer_aq(hw, offset, words, data);
+#endif
return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
}
@@ -401,9 +425,13 @@ enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
bool last_command)
{
enum i40e_status_code ret_code = I40E_ERR_NVM;
+ struct i40e_asq_cmd_details cmd_details;
DEBUGFUNC("i40e_read_nvm_aq");
+ memset(&cmd_details, 0, sizeof(cmd_details));
+ cmd_details.wb_desc = &hw->nvm_wb_desc;
+
/* Here we are checking the SR limit only for the flat memory model.
* We cannot do it for the module-based model, as we did not acquire
* the NVM resource yet (we cannot get the module pointer value).
@@ -428,7 +456,7 @@ enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
ret_code = i40e_aq_read_nvm(hw, module_pointer,
2 * offset, /*bytes*/
2 * words, /*bytes*/
- data, last_command, NULL);
+ data, last_command, &cmd_details);
return ret_code;
}
@@ -449,9 +477,13 @@ enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
bool last_command)
{
enum i40e_status_code ret_code = I40E_ERR_NVM;
+ struct i40e_asq_cmd_details cmd_details;
DEBUGFUNC("i40e_write_nvm_aq");
+ memset(&cmd_details, 0, sizeof(cmd_details));
+ cmd_details.wb_desc = &hw->nvm_wb_desc;
+
/* Here we are checking the SR limit only for the flat memory model.
* We cannot do it for the module-based model, as we did not acquire
* the NVM resource yet (we cannot get the module pointer value).
@@ -470,7 +502,7 @@ enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
ret_code = i40e_aq_update_nvm(hw, module_pointer,
2 * offset, /*bytes*/
2 * words, /*bytes*/
- data, last_command, NULL);
+ data, last_command, &cmd_details);
return ret_code;
}
@@ -580,6 +612,7 @@ enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
/* Read SR page */
if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
+
ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
if (ret_code != I40E_SUCCESS) {
ret_code = I40E_ERR_NVM_CHECKSUM;
@@ -625,13 +658,15 @@ enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw)
{
enum i40e_status_code ret_code = I40E_SUCCESS;
u16 checksum;
+ __le16 le_sum;
DEBUGFUNC("i40e_update_nvm_checksum");
ret_code = i40e_calc_nvm_checksum(hw, &checksum);
+ le_sum = CPU_TO_LE16(checksum);
if (ret_code == I40E_SUCCESS)
ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
- 1, &checksum, TRUE);
+ 1, &le_sum, TRUE);
return ret_code;
}
diff --git a/sys/dev/ixl/i40e_osdep.h b/sys/dev/ixl/i40e_osdep.h
index 83e89229c400..67a4b1868a09 100644
--- a/sys/dev/ixl/i40e_osdep.h
+++ b/sys/dev/ixl/i40e_osdep.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2013-2014, Intel Corporation
+ Copyright (c) 2013-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -112,6 +112,9 @@
#define FIELD_SIZEOF(x, y) (sizeof(((x*)0)->y))
+#define BIT(a) (1UL << (a))
+#define BIT_ULL(a) (1ULL << (a))
+
typedef uint8_t u8;
typedef int8_t s8;
typedef uint16_t u16;
@@ -189,7 +192,7 @@ rd32_osdep(struct i40e_osdep *osdep, uint32_t reg)
{
KASSERT(reg < osdep->mem_bus_space_size,
- ("ixl: register offset %#jx too large (max is %#jx",
+ ("ixl: register offset %#jx too large (max is %#jx)",
(uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size));
return (bus_space_read_4(osdep->mem_bus_space_tag,
@@ -201,7 +204,7 @@ wr32_osdep(struct i40e_osdep *osdep, uint32_t reg, uint32_t value)
{
KASSERT(reg < osdep->mem_bus_space_size,
- ("ixl: register offset %#jx too large (max is %#jx",
+ ("ixl: register offset %#jx too large (max is %#jx)",
(uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size));
bus_space_write_4(osdep->mem_bus_space_tag,
@@ -211,7 +214,6 @@ wr32_osdep(struct i40e_osdep *osdep, uint32_t reg, uint32_t value)
static __inline void
ixl_flush_osdep(struct i40e_osdep *osdep)
{
-
rd32_osdep(osdep, osdep->flush_reg);
}
diff --git a/sys/dev/ixl/i40e_prototype.h b/sys/dev/ixl/i40e_prototype.h
index d49b52da66fb..c2395d232ccd 100644
--- a/sys/dev/ixl/i40e_prototype.h
+++ b/sys/dev/ixl/i40e_prototype.h
@@ -78,6 +78,21 @@ void i40e_idle_aq(struct i40e_hw *hw);
void i40e_resume_aq(struct i40e_hw *hw);
bool i40e_check_asq_alive(struct i40e_hw *hw);
enum i40e_status_code i40e_aq_queue_shutdown(struct i40e_hw *hw, bool unloading);
+#ifdef X722_SUPPORT
+
+enum i40e_status_code i40e_aq_get_rss_lut(struct i40e_hw *hw, u16 seid,
+ bool pf_lut, u8 *lut, u16 lut_size);
+enum i40e_status_code i40e_aq_set_rss_lut(struct i40e_hw *hw, u16 seid,
+ bool pf_lut, u8 *lut, u16 lut_size);
+enum i40e_status_code i40e_aq_get_rss_key(struct i40e_hw *hw,
+ u16 seid,
+ struct i40e_aqc_get_set_rss_key_data *key);
+enum i40e_status_code i40e_aq_set_rss_key(struct i40e_hw *hw,
+ u16 seid,
+ struct i40e_aqc_get_set_rss_key_data *key);
+#endif
+char *i40e_aq_str(struct i40e_hw *hw, enum i40e_admin_queue_err aq_err);
+char *i40e_stat_str(struct i40e_hw *hw, enum i40e_status_code stat_err);
u32 i40e_led_get(struct i40e_hw *hw);
@@ -145,6 +160,12 @@ enum i40e_status_code i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
u16 vsi_id, bool set, struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_set_vsi_multicast_promiscuous(struct i40e_hw *hw,
u16 vsi_id, bool set, struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_set_vsi_mc_promisc_on_vlan(struct i40e_hw *hw,
+ u16 seid, bool enable, u16 vid,
+ struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
+ u16 seid, bool enable, u16 vid,
+ struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_get_vsi_params(struct i40e_hw *hw,
struct i40e_vsi_context *vsi_ctx,
struct i40e_asq_cmd_details *cmd_details);
@@ -204,6 +225,9 @@ enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw,
u8 cmd_flags, void *data, u16 buf_size,
u16 element_count,
struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_oem_post_update(struct i40e_hw *hw,
+ void *buff, u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_discover_capabilities(struct i40e_hw *hw,
void *buff, u16 buff_size, u16 *data_size,
enum i40e_admin_queue_opc list_type_opc,
@@ -377,7 +401,8 @@ enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw);
enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw);
void i40e_clear_hw(struct i40e_hw *hw);
void i40e_clear_pxe_mode(struct i40e_hw *hw);
-bool i40e_get_link_status(struct i40e_hw *hw);
+enum i40e_status_code i40e_get_link_status(struct i40e_hw *hw, bool *link_up);
+enum i40e_status_code i40e_update_link_info(struct i40e_hw *hw);
enum i40e_status_code i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
enum i40e_status_code i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
u32 *max_bw, u32 *min_bw, bool *min_valid, bool *max_valid);
@@ -445,4 +470,9 @@ enum i40e_status_code i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
u16 vsi_seid, u16 queue, bool is_add,
struct i40e_control_filter_stats *stats,
struct i40e_asq_cmd_details *cmd_details);
+enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
+ u8 table_id, u32 start_index, u16 buff_size,
+ void *buff, u16 *ret_buff_size,
+ u8 *ret_next_table, u32 *ret_next_index,
+ struct i40e_asq_cmd_details *cmd_details);
#endif /* _I40E_PROTOTYPE_H_ */
diff --git a/sys/dev/ixl/i40e_register.h b/sys/dev/ixl/i40e_register.h
index a8e47b3c94ad..adfc744c879e 100644
--- a/sys/dev/ixl/i40e_register.h
+++ b/sys/dev/ixl/i40e_register.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2013-2014, Intel Corporation
+ Copyright (c) 2013-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -882,6 +882,13 @@
#define I40E_PFINT_CEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT)
#define I40E_PFINT_CEQCTL_INTEVENT_SHIFT 31
#define I40E_PFINT_CEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_INTEVENT_SHIFT)
+#define I40E_GLINT_CTL 0x0003F800 /* Reset: CORER */
+#define I40E_GLINT_CTL_DIS_AUTOMASK_PF0_SHIFT 0
+#define I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_PF0_SHIFT)
+#define I40E_GLINT_CTL_DIS_AUTOMASK_VF0_SHIFT 1
+#define I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_VF0_SHIFT)
+#define I40E_GLINT_CTL_DIS_AUTOMASK_N_SHIFT 2
+#define I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_N_SHIFT)
#define I40E_PFINT_DYN_CTL0 0x00038480 /* Reset: PFR */
#define I40E_PFINT_DYN_CTL0_INTENA_SHIFT 0
#define I40E_PFINT_DYN_CTL0_INTENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_INTENA_SHIFT)
@@ -3375,4 +3382,1936 @@
#define I40E_VFQF_HREGION_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_VFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
#define I40E_VFQF_HREGION_REGION_7_SHIFT 29
#define I40E_VFQF_HREGION_REGION_7_MASK I40E_MASK(0x7, I40E_VFQF_HREGION_REGION_7_SHIFT)
+#ifdef X722_SUPPORT
+
+#define I40E_MNGSB_FDCRC 0x000B7050 /* Reset: POR */
+#define I40E_MNGSB_FDCRC_CRC_RES_SHIFT 0
+#define I40E_MNGSB_FDCRC_CRC_RES_MASK I40E_MASK(0xFF, I40E_MNGSB_FDCRC_CRC_RES_SHIFT)
+#define I40E_MNGSB_FDCS 0x000B7040 /* Reset: POR */
+#define I40E_MNGSB_FDCS_CRC_CONT_SHIFT 2
+#define I40E_MNGSB_FDCS_CRC_CONT_MASK I40E_MASK(0x1, I40E_MNGSB_FDCS_CRC_CONT_SHIFT)
+#define I40E_MNGSB_FDCS_CRC_SEED_EN_SHIFT 3
+#define I40E_MNGSB_FDCS_CRC_SEED_EN_MASK I40E_MASK(0x1, I40E_MNGSB_FDCS_CRC_SEED_EN_SHIFT)
+#define I40E_MNGSB_FDCS_CRC_WR_INH_SHIFT 4
+#define I40E_MNGSB_FDCS_CRC_WR_INH_MASK I40E_MASK(0x1, I40E_MNGSB_FDCS_CRC_WR_INH_SHIFT)
+#define I40E_MNGSB_FDCS_CRC_SEED_SHIFT 8
+#define I40E_MNGSB_FDCS_CRC_SEED_MASK I40E_MASK(0xFF, I40E_MNGSB_FDCS_CRC_SEED_SHIFT)
+#define I40E_MNGSB_FDS 0x000B7048 /* Reset: POR */
+#define I40E_MNGSB_FDS_START_BC_SHIFT 0
+#define I40E_MNGSB_FDS_START_BC_MASK I40E_MASK(0xFFF, I40E_MNGSB_FDS_START_BC_SHIFT)
+#define I40E_MNGSB_FDS_LAST_BC_SHIFT 16
+#define I40E_MNGSB_FDS_LAST_BC_MASK I40E_MASK(0xFFF, I40E_MNGSB_FDS_LAST_BC_SHIFT)
+
+#define I40E_GL_VF_CTRL_RX(_VF) (0x00083600 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
+#define I40E_GL_VF_CTRL_RX_MAX_INDEX 127
+#define I40E_GL_VF_CTRL_RX_AQ_RX_EN_SHIFT 0
+#define I40E_GL_VF_CTRL_RX_AQ_RX_EN_MASK I40E_MASK(0x1, I40E_GL_VF_CTRL_RX_AQ_RX_EN_SHIFT)
+#define I40E_GL_VF_CTRL_TX(_VF) (0x00083400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: EMPR */
+#define I40E_GL_VF_CTRL_TX_MAX_INDEX 127
+#define I40E_GL_VF_CTRL_TX_AQ_TX_EN_SHIFT 0
+#define I40E_GL_VF_CTRL_TX_AQ_TX_EN_MASK I40E_MASK(0x1, I40E_GL_VF_CTRL_TX_AQ_TX_EN_SHIFT)
+
+#define I40E_GLCM_LAN_CACHESIZE 0x0010C4D8 /* Reset: CORER */
+#define I40E_GLCM_LAN_CACHESIZE_WORD_SIZE_SHIFT 0
+#define I40E_GLCM_LAN_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFFF, I40E_GLCM_LAN_CACHESIZE_WORD_SIZE_SHIFT)
+#define I40E_GLCM_LAN_CACHESIZE_SETS_SHIFT 12
+#define I40E_GLCM_LAN_CACHESIZE_SETS_MASK I40E_MASK(0xF, I40E_GLCM_LAN_CACHESIZE_SETS_SHIFT)
+#define I40E_GLCM_LAN_CACHESIZE_WAYS_SHIFT 16
+#define I40E_GLCM_LAN_CACHESIZE_WAYS_MASK I40E_MASK(0x3FF, I40E_GLCM_LAN_CACHESIZE_WAYS_SHIFT)
+#define I40E_GLCM_PE_CACHESIZE 0x00138FE4 /* Reset: CORER */
+#define I40E_GLCM_PE_CACHESIZE_WORD_SIZE_SHIFT 0
+#define I40E_GLCM_PE_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFFF, I40E_GLCM_PE_CACHESIZE_WORD_SIZE_SHIFT)
+#define I40E_GLCM_PE_CACHESIZE_SETS_SHIFT 12
+#define I40E_GLCM_PE_CACHESIZE_SETS_MASK I40E_MASK(0xF, I40E_GLCM_PE_CACHESIZE_SETS_SHIFT)
+#define I40E_GLCM_PE_CACHESIZE_WAYS_SHIFT 16
+#define I40E_GLCM_PE_CACHESIZE_WAYS_MASK I40E_MASK(0x1FF, I40E_GLCM_PE_CACHESIZE_WAYS_SHIFT)
+#define I40E_PFCM_PE_ERRDATA 0x00138D00 /* Reset: PFR */
+#define I40E_PFCM_PE_ERRDATA_ERROR_CODE_SHIFT 0
+#define I40E_PFCM_PE_ERRDATA_ERROR_CODE_MASK I40E_MASK(0xF, I40E_PFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
+#define I40E_PFCM_PE_ERRDATA_Q_TYPE_SHIFT 4
+#define I40E_PFCM_PE_ERRDATA_Q_TYPE_MASK I40E_MASK(0x7, I40E_PFCM_PE_ERRDATA_Q_TYPE_SHIFT)
+#define I40E_PFCM_PE_ERRDATA_Q_NUM_SHIFT 8
+#define I40E_PFCM_PE_ERRDATA_Q_NUM_MASK I40E_MASK(0x3FFFF, I40E_PFCM_PE_ERRDATA_Q_NUM_SHIFT)
+#define I40E_PFCM_PE_ERRINFO 0x00138C80 /* Reset: PFR */
+#define I40E_PFCM_PE_ERRINFO_ERROR_VALID_SHIFT 0
+#define I40E_PFCM_PE_ERRINFO_ERROR_VALID_MASK I40E_MASK(0x1, I40E_PFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
+#define I40E_PFCM_PE_ERRINFO_ERROR_INST_SHIFT 4
+#define I40E_PFCM_PE_ERRINFO_ERROR_INST_MASK I40E_MASK(0x7, I40E_PFCM_PE_ERRINFO_ERROR_INST_SHIFT)
+#define I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT 8
+#define I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
+#define I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT 16
+#define I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
+#define I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT 24
+#define I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK I40E_MASK(0xFF, I40E_PFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
+
+#define I40E_PRTDCB_TFMSTC(_i) (0x000A0040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: CORER */
+#define I40E_PRTDCB_TFMSTC_MAX_INDEX 7
+#define I40E_PRTDCB_TFMSTC_MSTC_SHIFT 0
+#define I40E_PRTDCB_TFMSTC_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TFMSTC_MSTC_SHIFT)
+#define I40E_GL_FWSTS_FWROWD_SHIFT 8
+#define I40E_GL_FWSTS_FWROWD_MASK I40E_MASK(0x1, I40E_GL_FWSTS_FWROWD_SHIFT)
+#define I40E_GLFOC_CACHESIZE 0x000AA0DC /* Reset: CORER */
+#define I40E_GLFOC_CACHESIZE_WORD_SIZE_SHIFT 0
+#define I40E_GLFOC_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFF, I40E_GLFOC_CACHESIZE_WORD_SIZE_SHIFT)
+#define I40E_GLFOC_CACHESIZE_SETS_SHIFT 8
+#define I40E_GLFOC_CACHESIZE_SETS_MASK I40E_MASK(0xFFF, I40E_GLFOC_CACHESIZE_SETS_SHIFT)
+#define I40E_GLFOC_CACHESIZE_WAYS_SHIFT 20
+#define I40E_GLFOC_CACHESIZE_WAYS_MASK I40E_MASK(0xF, I40E_GLFOC_CACHESIZE_WAYS_SHIFT)
+#define I40E_GLHMC_APBVTINUSEBASE(_i) (0x000C4a00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_APBVTINUSEBASE_MAX_INDEX 15
+#define I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT 0
+#define I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_APBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT)
+#define I40E_GLHMC_CEQPART(_i) (0x001312C0 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_CEQPART_MAX_INDEX 15
+#define I40E_GLHMC_CEQPART_PMCEQBASE_SHIFT 0
+#define I40E_GLHMC_CEQPART_PMCEQBASE_MASK I40E_MASK(0xFF, I40E_GLHMC_CEQPART_PMCEQBASE_SHIFT)
+#define I40E_GLHMC_CEQPART_PMCEQSIZE_SHIFT 16
+#define I40E_GLHMC_CEQPART_PMCEQSIZE_MASK I40E_MASK(0x1FF, I40E_GLHMC_CEQPART_PMCEQSIZE_SHIFT)
+#define I40E_GLHMC_DBCQMAX 0x000C20F0 /* Reset: CORER */
+#define I40E_GLHMC_DBCQMAX_GLHMC_DBCQMAX_SHIFT 0
+#define I40E_GLHMC_DBCQMAX_GLHMC_DBCQMAX_MASK I40E_MASK(0x3FFFF, I40E_GLHMC_DBCQMAX_GLHMC_DBCQMAX_SHIFT)
+#define I40E_GLHMC_DBCQPART(_i) (0x00131240 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_DBCQPART_MAX_INDEX 15
+#define I40E_GLHMC_DBCQPART_PMDBCQBASE_SHIFT 0
+#define I40E_GLHMC_DBCQPART_PMDBCQBASE_MASK I40E_MASK(0x3FFF, I40E_GLHMC_DBCQPART_PMDBCQBASE_SHIFT)
+#define I40E_GLHMC_DBCQPART_PMDBCQSIZE_SHIFT 16
+#define I40E_GLHMC_DBCQPART_PMDBCQSIZE_MASK I40E_MASK(0x7FFF, I40E_GLHMC_DBCQPART_PMDBCQSIZE_SHIFT)
+#define I40E_GLHMC_DBQPMAX 0x000C20EC /* Reset: CORER */
+#define I40E_GLHMC_DBQPMAX_GLHMC_DBQPMAX_SHIFT 0
+#define I40E_GLHMC_DBQPMAX_GLHMC_DBQPMAX_MASK I40E_MASK(0x7FFFF, I40E_GLHMC_DBQPMAX_GLHMC_DBQPMAX_SHIFT)
+#define I40E_GLHMC_DBQPPART(_i) (0x00138D80 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_DBQPPART_MAX_INDEX 15
+#define I40E_GLHMC_DBQPPART_PMDBQPBASE_SHIFT 0
+#define I40E_GLHMC_DBQPPART_PMDBQPBASE_MASK I40E_MASK(0x3FFF, I40E_GLHMC_DBQPPART_PMDBQPBASE_SHIFT)
+#define I40E_GLHMC_DBQPPART_PMDBQPSIZE_SHIFT 16
+#define I40E_GLHMC_DBQPPART_PMDBQPSIZE_MASK I40E_MASK(0x7FFF, I40E_GLHMC_DBQPPART_PMDBQPSIZE_SHIFT)
+#define I40E_GLHMC_PEARPBASE(_i) (0x000C4800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEARPBASE_MAX_INDEX 15
+#define I40E_GLHMC_PEARPBASE_FPMPEARPBASE_SHIFT 0
+#define I40E_GLHMC_PEARPBASE_FPMPEARPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEARPBASE_FPMPEARPBASE_SHIFT)
+#define I40E_GLHMC_PEARPCNT(_i) (0x000C4900 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEARPCNT_MAX_INDEX 15
+#define I40E_GLHMC_PEARPCNT_FPMPEARPCNT_SHIFT 0
+#define I40E_GLHMC_PEARPCNT_FPMPEARPCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEARPCNT_FPMPEARPCNT_SHIFT)
+#define I40E_GLHMC_PEARPMAX 0x000C2038 /* Reset: CORER */
+#define I40E_GLHMC_PEARPMAX_PMPEARPMAX_SHIFT 0
+#define I40E_GLHMC_PEARPMAX_PMPEARPMAX_MASK I40E_MASK(0x1FFFF, I40E_GLHMC_PEARPMAX_PMPEARPMAX_SHIFT)
+#define I40E_GLHMC_PEARPOBJSZ 0x000C2034 /* Reset: CORER */
+#define I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_SHIFT 0
+#define I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_MASK I40E_MASK(0x7, I40E_GLHMC_PEARPOBJSZ_PMPEARPOBJSZ_SHIFT)
+#define I40E_GLHMC_PECQBASE(_i) (0x000C4200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PECQBASE_MAX_INDEX 15
+#define I40E_GLHMC_PECQBASE_FPMPECQBASE_SHIFT 0
+#define I40E_GLHMC_PECQBASE_FPMPECQBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PECQBASE_FPMPECQBASE_SHIFT)
+#define I40E_GLHMC_PECQCNT(_i) (0x000C4300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PECQCNT_MAX_INDEX 15
+#define I40E_GLHMC_PECQCNT_FPMPECQCNT_SHIFT 0
+#define I40E_GLHMC_PECQCNT_FPMPECQCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PECQCNT_FPMPECQCNT_SHIFT)
+#define I40E_GLHMC_PECQOBJSZ 0x000C2020 /* Reset: CORER */
+#define I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_SHIFT 0
+#define I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PECQOBJSZ_PMPECQOBJSZ_SHIFT)
+#define I40E_GLHMC_PEHTCNT(_i) (0x000C4700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEHTCNT_MAX_INDEX 15
+#define I40E_GLHMC_PEHTCNT_FPMPEHTCNT_SHIFT 0
+#define I40E_GLHMC_PEHTCNT_FPMPEHTCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEHTCNT_FPMPEHTCNT_SHIFT)
+#define I40E_GLHMC_PEHTEBASE(_i) (0x000C4600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEHTEBASE_MAX_INDEX 15
+#define I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_SHIFT 0
+#define I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEHTEBASE_FPMPEHTEBASE_SHIFT)
+#define I40E_GLHMC_PEHTEOBJSZ 0x000C202c /* Reset: CORER */
+#define I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_SHIFT 0
+#define I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEHTEOBJSZ_PMPEHTEOBJSZ_SHIFT)
+#define I40E_GLHMC_PEHTMAX 0x000C2030 /* Reset: CORER */
+#define I40E_GLHMC_PEHTMAX_PMPEHTMAX_SHIFT 0
+#define I40E_GLHMC_PEHTMAX_PMPEHTMAX_MASK I40E_MASK(0x1FFFFF, I40E_GLHMC_PEHTMAX_PMPEHTMAX_SHIFT)
+#define I40E_GLHMC_PEMRBASE(_i) (0x000C4c00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEMRBASE_MAX_INDEX 15
+#define I40E_GLHMC_PEMRBASE_FPMPEMRBASE_SHIFT 0
+#define I40E_GLHMC_PEMRBASE_FPMPEMRBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEMRBASE_FPMPEMRBASE_SHIFT)
+#define I40E_GLHMC_PEMRCNT(_i) (0x000C4d00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEMRCNT_MAX_INDEX 15
+#define I40E_GLHMC_PEMRCNT_FPMPEMRSZ_SHIFT 0
+#define I40E_GLHMC_PEMRCNT_FPMPEMRSZ_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEMRCNT_FPMPEMRSZ_SHIFT)
+#define I40E_GLHMC_PEMRMAX 0x000C2040 /* Reset: CORER */
+#define I40E_GLHMC_PEMRMAX_PMPEMRMAX_SHIFT 0
+#define I40E_GLHMC_PEMRMAX_PMPEMRMAX_MASK I40E_MASK(0x7FFFFF, I40E_GLHMC_PEMRMAX_PMPEMRMAX_SHIFT)
+#define I40E_GLHMC_PEMROBJSZ 0x000C203c /* Reset: CORER */
+#define I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_SHIFT 0
+#define I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEMROBJSZ_PMPEMROBJSZ_SHIFT)
+#define I40E_GLHMC_PEPBLBASE(_i) (0x000C5800 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEPBLBASE_MAX_INDEX 15
+#define I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_SHIFT 0
+#define I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEPBLBASE_FPMPEPBLBASE_SHIFT)
+#define I40E_GLHMC_PEPBLCNT(_i) (0x000C5900 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEPBLCNT_MAX_INDEX 15
+#define I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_SHIFT 0
+#define I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEPBLCNT_FPMPEPBLCNT_SHIFT)
+#define I40E_GLHMC_PEPBLMAX 0x000C206c /* Reset: CORER */
+#define I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_SHIFT 0
+#define I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEPBLMAX_PMPEPBLMAX_SHIFT)
+#define I40E_GLHMC_PEPFFIRSTSD 0x000C20E4 /* Reset: CORER */
+#define I40E_GLHMC_PEPFFIRSTSD_GLHMC_PEPFFIRSTSD_SHIFT 0
+#define I40E_GLHMC_PEPFFIRSTSD_GLHMC_PEPFFIRSTSD_MASK I40E_MASK(0xFFF, I40E_GLHMC_PEPFFIRSTSD_GLHMC_PEPFFIRSTSD_SHIFT)
+#define I40E_GLHMC_PEQ1BASE(_i) (0x000C5200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEQ1BASE_MAX_INDEX 15
+#define I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_SHIFT 0
+#define I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEQ1BASE_FPMPEQ1BASE_SHIFT)
+#define I40E_GLHMC_PEQ1CNT(_i) (0x000C5300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEQ1CNT_MAX_INDEX 15
+#define I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_SHIFT 0
+#define I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEQ1CNT_FPMPEQ1CNT_SHIFT)
+#define I40E_GLHMC_PEQ1FLBASE(_i) (0x000C5400 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEQ1FLBASE_MAX_INDEX 15
+#define I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_SHIFT 0
+#define I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEQ1FLBASE_FPMPEQ1FLBASE_SHIFT)
+#define I40E_GLHMC_PEQ1FLMAX 0x000C2058 /* Reset: CORER */
+#define I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_SHIFT 0
+#define I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_MASK I40E_MASK(0x3FFFFFF, I40E_GLHMC_PEQ1FLMAX_PMPEQ1FLMAX_SHIFT)
+#define I40E_GLHMC_PEQ1MAX 0x000C2054 /* Reset: CORER */
+#define I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_SHIFT 0
+#define I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_MASK I40E_MASK(0x3FFFFFF, I40E_GLHMC_PEQ1MAX_PMPEQ1MAX_SHIFT)
+#define I40E_GLHMC_PEQ1OBJSZ 0x000C2050 /* Reset: CORER */
+#define I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_SHIFT 0
+#define I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEQ1OBJSZ_PMPEQ1OBJSZ_SHIFT)
+#define I40E_GLHMC_PEQPBASE(_i) (0x000C4000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEQPBASE_MAX_INDEX 15
+#define I40E_GLHMC_PEQPBASE_FPMPEQPBASE_SHIFT 0
+#define I40E_GLHMC_PEQPBASE_FPMPEQPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEQPBASE_FPMPEQPBASE_SHIFT)
+#define I40E_GLHMC_PEQPCNT(_i) (0x000C4100 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEQPCNT_MAX_INDEX 15
+#define I40E_GLHMC_PEQPCNT_FPMPEQPCNT_SHIFT 0
+#define I40E_GLHMC_PEQPCNT_FPMPEQPCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEQPCNT_FPMPEQPCNT_SHIFT)
+#define I40E_GLHMC_PEQPOBJSZ 0x000C201c /* Reset: CORER */
+#define I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_SHIFT 0
+#define I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEQPOBJSZ_PMPEQPOBJSZ_SHIFT)
+#define I40E_GLHMC_PESRQBASE(_i) (0x000C4400 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PESRQBASE_MAX_INDEX 15
+#define I40E_GLHMC_PESRQBASE_FPMPESRQBASE_SHIFT 0
+#define I40E_GLHMC_PESRQBASE_FPMPESRQBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PESRQBASE_FPMPESRQBASE_SHIFT)
+#define I40E_GLHMC_PESRQCNT(_i) (0x000C4500 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PESRQCNT_MAX_INDEX 15
+#define I40E_GLHMC_PESRQCNT_FPMPESRQCNT_SHIFT 0
+#define I40E_GLHMC_PESRQCNT_FPMPESRQCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PESRQCNT_FPMPESRQCNT_SHIFT)
+#define I40E_GLHMC_PESRQMAX 0x000C2028 /* Reset: CORER */
+#define I40E_GLHMC_PESRQMAX_PMPESRQMAX_SHIFT 0
+#define I40E_GLHMC_PESRQMAX_PMPESRQMAX_MASK I40E_MASK(0xFFFF, I40E_GLHMC_PESRQMAX_PMPESRQMAX_SHIFT)
+#define I40E_GLHMC_PESRQOBJSZ 0x000C2024 /* Reset: CORER */
+#define I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_SHIFT 0
+#define I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PESRQOBJSZ_PMPESRQOBJSZ_SHIFT)
+#define I40E_GLHMC_PETIMERBASE(_i) (0x000C5A00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PETIMERBASE_MAX_INDEX 15
+#define I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_SHIFT 0
+#define I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PETIMERBASE_FPMPETIMERBASE_SHIFT)
+#define I40E_GLHMC_PETIMERCNT(_i) (0x000C5B00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PETIMERCNT_MAX_INDEX 15
+#define I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_SHIFT 0
+#define I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PETIMERCNT_FPMPETIMERCNT_SHIFT)
+#define I40E_GLHMC_PETIMERMAX 0x000C2084 /* Reset: CORER */
+#define I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_SHIFT 0
+#define I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PETIMERMAX_PMPETIMERMAX_SHIFT)
+#define I40E_GLHMC_PETIMEROBJSZ 0x000C2080 /* Reset: CORER */
+#define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT 0
+#define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT)
+#define I40E_GLHMC_PEXFBASE(_i) (0x000C4e00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEXFBASE_MAX_INDEX 15
+#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT 0
+#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT)
+#define I40E_GLHMC_PEXFCNT(_i) (0x000C4f00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEXFCNT_MAX_INDEX 15
+#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT 0
+#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT)
+#define I40E_GLHMC_PEXFFLBASE(_i) (0x000C5000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PEXFFLBASE_MAX_INDEX 15
+#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT 0
+#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT)
+#define I40E_GLHMC_PEXFFLMAX 0x000C204c /* Reset: CORER */
+#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT 0
+#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_MASK I40E_MASK(0x1FFFFFF, I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT)
+#define I40E_GLHMC_PEXFMAX 0x000C2048 /* Reset: CORER */
+#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT 0
+#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_MASK I40E_MASK(0x3FFFFFF, I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT)
+#define I40E_GLHMC_PEXFOBJSZ 0x000C2044 /* Reset: CORER */
+#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT 0
+#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT)
+#define I40E_GLHMC_PFPESDPART(_i) (0x000C0880 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLHMC_PFPESDPART_MAX_INDEX 15
+#define I40E_GLHMC_PFPESDPART_PMSDBASE_SHIFT 0
+#define I40E_GLHMC_PFPESDPART_PMSDBASE_MASK I40E_MASK(0xFFF, I40E_GLHMC_PFPESDPART_PMSDBASE_SHIFT)
+#define I40E_GLHMC_PFPESDPART_PMSDSIZE_SHIFT 16
+#define I40E_GLHMC_PFPESDPART_PMSDSIZE_MASK I40E_MASK(0x1FFF, I40E_GLHMC_PFPESDPART_PMSDSIZE_SHIFT)
+#define I40E_GLHMC_VFAPBVTINUSEBASE(_i) (0x000Cca00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFAPBVTINUSEBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT 0
+#define I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFAPBVTINUSEBASE_FPMAPBINUSEBASE_SHIFT)
+#define I40E_GLHMC_VFCEQPART(_i) (0x00132240 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFCEQPART_MAX_INDEX 31
+#define I40E_GLHMC_VFCEQPART_PMCEQBASE_SHIFT 0
+#define I40E_GLHMC_VFCEQPART_PMCEQBASE_MASK I40E_MASK(0xFF, I40E_GLHMC_VFCEQPART_PMCEQBASE_SHIFT)
+#define I40E_GLHMC_VFCEQPART_PMCEQSIZE_SHIFT 16
+#define I40E_GLHMC_VFCEQPART_PMCEQSIZE_MASK I40E_MASK(0x1FF, I40E_GLHMC_VFCEQPART_PMCEQSIZE_SHIFT)
+#define I40E_GLHMC_VFDBCQPART(_i) (0x00132140 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFDBCQPART_MAX_INDEX 31
+#define I40E_GLHMC_VFDBCQPART_PMDBCQBASE_SHIFT 0
+#define I40E_GLHMC_VFDBCQPART_PMDBCQBASE_MASK I40E_MASK(0x3FFF, I40E_GLHMC_VFDBCQPART_PMDBCQBASE_SHIFT)
+#define I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_SHIFT 16
+#define I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_MASK I40E_MASK(0x7FFF, I40E_GLHMC_VFDBCQPART_PMDBCQSIZE_SHIFT)
+#define I40E_GLHMC_VFDBQPPART(_i) (0x00138E00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFDBQPPART_MAX_INDEX 31
+#define I40E_GLHMC_VFDBQPPART_PMDBQPBASE_SHIFT 0
+#define I40E_GLHMC_VFDBQPPART_PMDBQPBASE_MASK I40E_MASK(0x3FFF, I40E_GLHMC_VFDBQPPART_PMDBQPBASE_SHIFT)
+#define I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_SHIFT 16
+#define I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_MASK I40E_MASK(0x7FFF, I40E_GLHMC_VFDBQPPART_PMDBQPSIZE_SHIFT)
+#define I40E_GLHMC_VFFSIAVBASE(_i) (0x000Cd600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFFSIAVBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_SHIFT 0
+#define I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFFSIAVBASE_FPMFSIAVBASE_SHIFT)
+#define I40E_GLHMC_VFFSIAVCNT(_i) (0x000Cd700 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFFSIAVCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_SHIFT 0
+#define I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFFSIAVCNT_FPMFSIAVCNT_SHIFT)
+#define I40E_GLHMC_VFPDINV(_i) (0x000C8300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPDINV_MAX_INDEX 31
+#define I40E_GLHMC_VFPDINV_PMSDIDX_SHIFT 0
+#define I40E_GLHMC_VFPDINV_PMSDIDX_MASK I40E_MASK(0xFFF, I40E_GLHMC_VFPDINV_PMSDIDX_SHIFT)
+#define I40E_GLHMC_VFPDINV_PMSDPARTSEL_SHIFT 15
+#define I40E_GLHMC_VFPDINV_PMSDPARTSEL_MASK I40E_MASK(0x1, I40E_GLHMC_VFPDINV_PMSDPARTSEL_SHIFT)
+#define I40E_GLHMC_VFPDINV_PMPDIDX_SHIFT 16
+#define I40E_GLHMC_VFPDINV_PMPDIDX_MASK I40E_MASK(0x1FF, I40E_GLHMC_VFPDINV_PMPDIDX_SHIFT)
+#define I40E_GLHMC_VFPEARPBASE(_i) (0x000Cc800 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEARPBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_SHIFT 0
+#define I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEARPBASE_FPMPEARPBASE_SHIFT)
+#define I40E_GLHMC_VFPEARPCNT(_i) (0x000Cc900 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEARPCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_SHIFT 0
+#define I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEARPCNT_FPMPEARPCNT_SHIFT)
+#define I40E_GLHMC_VFPECQBASE(_i) (0x000Cc200 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPECQBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPECQBASE_FPMPECQBASE_SHIFT 0
+#define I40E_GLHMC_VFPECQBASE_FPMPECQBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPECQBASE_FPMPECQBASE_SHIFT)
+#define I40E_GLHMC_VFPECQCNT(_i) (0x000Cc300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPECQCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPECQCNT_FPMPECQCNT_SHIFT 0
+#define I40E_GLHMC_VFPECQCNT_FPMPECQCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPECQCNT_FPMPECQCNT_SHIFT)
+#define I40E_GLHMC_VFPEHTCNT(_i) (0x000Cc700 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEHTCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_SHIFT 0
+#define I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEHTCNT_FPMPEHTCNT_SHIFT)
+#define I40E_GLHMC_VFPEHTEBASE(_i) (0x000Cc600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEHTEBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_SHIFT 0
+#define I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEHTEBASE_FPMPEHTEBASE_SHIFT)
+#define I40E_GLHMC_VFPEMRBASE(_i) (0x000Ccc00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEMRBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_SHIFT 0
+#define I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEMRBASE_FPMPEMRBASE_SHIFT)
+#define I40E_GLHMC_VFPEMRCNT(_i) (0x000Ccd00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEMRCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_SHIFT 0
+#define I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEMRCNT_FPMPEMRSZ_SHIFT)
+#define I40E_GLHMC_VFPEPBLBASE(_i) (0x000Cd800 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEPBLBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_SHIFT 0
+#define I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEPBLBASE_FPMPEPBLBASE_SHIFT)
+#define I40E_GLHMC_VFPEPBLCNT(_i) (0x000Cd900 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEPBLCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_SHIFT 0
+#define I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEPBLCNT_FPMPEPBLCNT_SHIFT)
+#define I40E_GLHMC_VFPEQ1BASE(_i) (0x000Cd200 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEQ1BASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_SHIFT 0
+#define I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEQ1BASE_FPMPEQ1BASE_SHIFT)
+#define I40E_GLHMC_VFPEQ1CNT(_i) (0x000Cd300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEQ1CNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_SHIFT 0
+#define I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEQ1CNT_FPMPEQ1CNT_SHIFT)
+#define I40E_GLHMC_VFPEQ1FLBASE(_i) (0x000Cd400 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEQ1FLBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_SHIFT 0
+#define I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEQ1FLBASE_FPMPEQ1FLBASE_SHIFT)
+#define I40E_GLHMC_VFPEQPBASE(_i) (0x000Cc000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEQPBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_SHIFT 0
+#define I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEQPBASE_FPMPEQPBASE_SHIFT)
+#define I40E_GLHMC_VFPEQPCNT(_i) (0x000Cc100 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEQPCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_SHIFT 0
+#define I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEQPCNT_FPMPEQPCNT_SHIFT)
+#define I40E_GLHMC_VFPESRQBASE(_i) (0x000Cc400 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPESRQBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_SHIFT 0
+#define I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPESRQBASE_FPMPESRQBASE_SHIFT)
+#define I40E_GLHMC_VFPESRQCNT(_i) (0x000Cc500 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPESRQCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_SHIFT 0
+#define I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPESRQCNT_FPMPESRQCNT_SHIFT)
+#define I40E_GLHMC_VFPETIMERBASE(_i) (0x000CDA00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPETIMERBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_SHIFT 0
+#define I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPETIMERBASE_FPMPETIMERBASE_SHIFT)
+#define I40E_GLHMC_VFPETIMERCNT(_i) (0x000CDB00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPETIMERCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT 0
+#define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT)
+#define I40E_GLHMC_VFPEXFBASE(_i) (0x000Cce00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEXFBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT 0
+#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT)
+#define I40E_GLHMC_VFPEXFCNT(_i) (0x000Ccf00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEXFCNT_MAX_INDEX 31
+#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT 0
+#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT)
+#define I40E_GLHMC_VFPEXFFLBASE(_i) (0x000Cd000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFPEXFFLBASE_MAX_INDEX 31
+#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT 0
+#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT)
+#define I40E_GLHMC_VFSDPART(_i) (0x000C8800 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLHMC_VFSDPART_MAX_INDEX 31
+#define I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT 0
+#define I40E_GLHMC_VFSDPART_PMSDBASE_MASK I40E_MASK(0xFFF, I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT)
+#define I40E_GLHMC_VFSDPART_PMSDSIZE_SHIFT 16
+#define I40E_GLHMC_VFSDPART_PMSDSIZE_MASK I40E_MASK(0x1FFF, I40E_GLHMC_VFSDPART_PMSDSIZE_SHIFT)
+#define I40E_GLPBLOC_CACHESIZE 0x000A80BC /* Reset: CORER */
+#define I40E_GLPBLOC_CACHESIZE_WORD_SIZE_SHIFT 0
+#define I40E_GLPBLOC_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFF, I40E_GLPBLOC_CACHESIZE_WORD_SIZE_SHIFT)
+#define I40E_GLPBLOC_CACHESIZE_SETS_SHIFT 8
+#define I40E_GLPBLOC_CACHESIZE_SETS_MASK I40E_MASK(0xFFF, I40E_GLPBLOC_CACHESIZE_SETS_SHIFT)
+#define I40E_GLPBLOC_CACHESIZE_WAYS_SHIFT 20
+#define I40E_GLPBLOC_CACHESIZE_WAYS_MASK I40E_MASK(0xF, I40E_GLPBLOC_CACHESIZE_WAYS_SHIFT)
+#define I40E_GLPDOC_CACHESIZE 0x000D0088 /* Reset: CORER */
+#define I40E_GLPDOC_CACHESIZE_WORD_SIZE_SHIFT 0
+#define I40E_GLPDOC_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFF, I40E_GLPDOC_CACHESIZE_WORD_SIZE_SHIFT)
+#define I40E_GLPDOC_CACHESIZE_SETS_SHIFT 8
+#define I40E_GLPDOC_CACHESIZE_SETS_MASK I40E_MASK(0xFFF, I40E_GLPDOC_CACHESIZE_SETS_SHIFT)
+#define I40E_GLPDOC_CACHESIZE_WAYS_SHIFT 20
+#define I40E_GLPDOC_CACHESIZE_WAYS_MASK I40E_MASK(0xF, I40E_GLPDOC_CACHESIZE_WAYS_SHIFT)
+#define I40E_GLPEOC_CACHESIZE 0x000A60E8 /* Reset: CORER */
+#define I40E_GLPEOC_CACHESIZE_WORD_SIZE_SHIFT 0
+#define I40E_GLPEOC_CACHESIZE_WORD_SIZE_MASK I40E_MASK(0xFF, I40E_GLPEOC_CACHESIZE_WORD_SIZE_SHIFT)
+#define I40E_GLPEOC_CACHESIZE_SETS_SHIFT 8
+#define I40E_GLPEOC_CACHESIZE_SETS_MASK I40E_MASK(0xFFF, I40E_GLPEOC_CACHESIZE_SETS_SHIFT)
+#define I40E_GLPEOC_CACHESIZE_WAYS_SHIFT 20
+#define I40E_GLPEOC_CACHESIZE_WAYS_MASK I40E_MASK(0xF, I40E_GLPEOC_CACHESIZE_WAYS_SHIFT)
+#define I40E_PFHMC_PDINV_PMSDPARTSEL_SHIFT 15
+#define I40E_PFHMC_PDINV_PMSDPARTSEL_MASK I40E_MASK(0x1, I40E_PFHMC_PDINV_PMSDPARTSEL_SHIFT)
+#define I40E_PFHMC_SDCMD_PMSDPARTSEL_SHIFT 15
+#define I40E_PFHMC_SDCMD_PMSDPARTSEL_MASK I40E_MASK(0x1, I40E_PFHMC_SDCMD_PMSDPARTSEL_SHIFT)
+#define I40E_GL_PPRS_SPARE 0x000856E0 /* Reset: CORER */
+#define I40E_GL_PPRS_SPARE_GL_PPRS_SPARE_SHIFT 0
+#define I40E_GL_PPRS_SPARE_GL_PPRS_SPARE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_PPRS_SPARE_GL_PPRS_SPARE_SHIFT)
+#define I40E_GL_TLAN_SPARE 0x000E64E0 /* Reset: CORER */
+#define I40E_GL_TLAN_SPARE_GL_TLAN_SPARE_SHIFT 0
+#define I40E_GL_TLAN_SPARE_GL_TLAN_SPARE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_TLAN_SPARE_GL_TLAN_SPARE_SHIFT)
+#define I40E_GL_TUPM_SPARE 0x000a2230 /* Reset: CORER */
+#define I40E_GL_TUPM_SPARE_GL_TUPM_SPARE_SHIFT 0
+#define I40E_GL_TUPM_SPARE_GL_TUPM_SPARE_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_TUPM_SPARE_GL_TUPM_SPARE_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG 0x000B81C0 /* Reset: POR */
+#define I40E_GLGEN_CAR_DEBUG_CAR_UPPER_CORE_CLK_EN_SHIFT 0
+#define I40E_GLGEN_CAR_DEBUG_CAR_UPPER_CORE_CLK_EN_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_UPPER_CORE_CLK_EN_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_HIU_CLK_EN_SHIFT 1
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_HIU_CLK_EN_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_HIU_CLK_EN_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_PE_CLK_EN_SHIFT 2
+#define I40E_GLGEN_CAR_DEBUG_CAR_PE_CLK_EN_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PE_CLK_EN_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_PRIM_CLK_ACTIVE_SHIFT 3
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_PRIM_CLK_ACTIVE_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_PRIM_CLK_ACTIVE_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CDC_PE_ACTIVE_SHIFT 4
+#define I40E_GLGEN_CAR_DEBUG_CDC_PE_ACTIVE_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CDC_PE_ACTIVE_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_PRST_RESET_N_SHIFT 5
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_PRST_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_PRST_RESET_N_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_SCLR_RESET_N_SHIFT 6
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_SCLR_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_SCLR_RESET_N_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IB_RESET_N_SHIFT 7
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IB_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IB_RESET_N_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IMIB_RESET_N_SHIFT 8
+#define I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IMIB_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_PCIE_RAW_IMIB_RESET_N_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_EMP_RESET_N_SHIFT 9
+#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_EMP_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_RAW_EMP_RESET_N_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_GLOBAL_RESET_N_SHIFT 10
+#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_GLOBAL_RESET_N_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_RAW_GLOBAL_RESET_N_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_LAN_POWER_GOOD_SHIFT 11
+#define I40E_GLGEN_CAR_DEBUG_CAR_RAW_LAN_POWER_GOOD_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CAR_RAW_LAN_POWER_GOOD_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_CDC_IOSF_PRIMERY_RST_B_SHIFT 12
+#define I40E_GLGEN_CAR_DEBUG_CDC_IOSF_PRIMERY_RST_B_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_CDC_IOSF_PRIMERY_RST_B_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_GBE_GLOBALRST_B_SHIFT 13
+#define I40E_GLGEN_CAR_DEBUG_GBE_GLOBALRST_B_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_GBE_GLOBALRST_B_SHIFT)
+#define I40E_GLGEN_CAR_DEBUG_FLEEP_AL_GLOBR_DONE_SHIFT 14
+#define I40E_GLGEN_CAR_DEBUG_FLEEP_AL_GLOBR_DONE_MASK I40E_MASK(0x1, I40E_GLGEN_CAR_DEBUG_FLEEP_AL_GLOBR_DONE_SHIFT)
+#define I40E_GLGEN_MISC_SPARE 0x000880E0 /* Reset: POR */
+#define I40E_GLGEN_MISC_SPARE_GLGEN_MISC_SPARE_SHIFT 0
+#define I40E_GLGEN_MISC_SPARE_GLGEN_MISC_SPARE_MASK I40E_MASK(0xFFFFFFFF, I40E_GLGEN_MISC_SPARE_GLGEN_MISC_SPARE_SHIFT)
+#define I40E_GL_UFUSE_SOC 0x000BE550 /* Reset: POR */
+#define I40E_GL_UFUSE_SOC_PORT_MODE_SHIFT 0
+#define I40E_GL_UFUSE_SOC_PORT_MODE_MASK I40E_MASK(0x3, I40E_GL_UFUSE_SOC_PORT_MODE_SHIFT)
+#define I40E_GL_UFUSE_SOC_NIC_ID_SHIFT 2
+#define I40E_GL_UFUSE_SOC_NIC_ID_MASK I40E_MASK(0x1, I40E_GL_UFUSE_SOC_NIC_ID_SHIFT)
+#define I40E_GL_UFUSE_SOC_SPARE_FUSES_SHIFT 3
+#define I40E_GL_UFUSE_SOC_SPARE_FUSES_MASK I40E_MASK(0x1FFF, I40E_GL_UFUSE_SOC_SPARE_FUSES_SHIFT)
+#define I40E_PFINT_DYN_CTL0_WB_ON_ITR_SHIFT 30
+#define I40E_PFINT_DYN_CTL0_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_WB_ON_ITR_SHIFT)
+#define I40E_PFINT_DYN_CTLN_WB_ON_ITR_SHIFT 30
+#define I40E_PFINT_DYN_CTLN_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_WB_ON_ITR_SHIFT)
+#define I40E_VFINT_DYN_CTL0_WB_ON_ITR_SHIFT 30
+#define I40E_VFINT_DYN_CTL0_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL0_WB_ON_ITR_SHIFT)
+#define I40E_VFINT_DYN_CTLN_WB_ON_ITR_SHIFT 30
+#define I40E_VFINT_DYN_CTLN_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN_WB_ON_ITR_SHIFT)
+#define I40E_VPLAN_QBASE(_VF) (0x00074800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VPLAN_QBASE_MAX_INDEX 127
+#define I40E_VPLAN_QBASE_VFFIRSTQ_SHIFT 0
+#define I40E_VPLAN_QBASE_VFFIRSTQ_MASK I40E_MASK(0x7FF, I40E_VPLAN_QBASE_VFFIRSTQ_SHIFT)
+#define I40E_VPLAN_QBASE_VFNUMQ_SHIFT 11
+#define I40E_VPLAN_QBASE_VFNUMQ_MASK I40E_MASK(0xFF, I40E_VPLAN_QBASE_VFNUMQ_SHIFT)
+#define I40E_VPLAN_QBASE_VFQTABLE_ENA_SHIFT 31
+#define I40E_VPLAN_QBASE_VFQTABLE_ENA_MASK I40E_MASK(0x1, I40E_VPLAN_QBASE_VFQTABLE_ENA_SHIFT)
+#define I40E_PRTMAC_LINK_DOWN_COUNTER 0x001E2440 /* Reset: GLOBR */
+#define I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_SHIFT 0
+#define I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_SHIFT)
+#define I40E_GLNVM_AL_REQ 0x000B6164 /* Reset: POR */
+#define I40E_GLNVM_AL_REQ_POR_SHIFT 0
+#define I40E_GLNVM_AL_REQ_POR_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_POR_SHIFT)
+#define I40E_GLNVM_AL_REQ_PCIE_IMIB_SHIFT 1
+#define I40E_GLNVM_AL_REQ_PCIE_IMIB_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_PCIE_IMIB_SHIFT)
+#define I40E_GLNVM_AL_REQ_GLOBR_SHIFT 2
+#define I40E_GLNVM_AL_REQ_GLOBR_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_GLOBR_SHIFT)
+#define I40E_GLNVM_AL_REQ_CORER_SHIFT 3
+#define I40E_GLNVM_AL_REQ_CORER_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_CORER_SHIFT)
+#define I40E_GLNVM_AL_REQ_PE_SHIFT 4
+#define I40E_GLNVM_AL_REQ_PE_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_PE_SHIFT)
+#define I40E_GLNVM_AL_REQ_PCIE_IMIB_ASSERT_SHIFT 5
+#define I40E_GLNVM_AL_REQ_PCIE_IMIB_ASSERT_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_PCIE_IMIB_ASSERT_SHIFT)
+#define I40E_GLNVM_ALTIMERS 0x000B6140 /* Reset: POR */
+#define I40E_GLNVM_ALTIMERS_PCI_ALTIMER_SHIFT 0
+#define I40E_GLNVM_ALTIMERS_PCI_ALTIMER_MASK I40E_MASK(0xFFF, I40E_GLNVM_ALTIMERS_PCI_ALTIMER_SHIFT)
+#define I40E_GLNVM_ALTIMERS_GEN_ALTIMER_SHIFT 12
+#define I40E_GLNVM_ALTIMERS_GEN_ALTIMER_MASK I40E_MASK(0xFFFFF, I40E_GLNVM_ALTIMERS_GEN_ALTIMER_SHIFT)
+#define I40E_GLNVM_FLA 0x000B6108 /* Reset: POR */
+#define I40E_GLNVM_FLA_LOCKED_SHIFT 6
+#define I40E_GLNVM_FLA_LOCKED_MASK I40E_MASK(0x1, I40E_GLNVM_FLA_LOCKED_SHIFT)
+
+#define I40E_GLNVM_ULD 0x000B6008 /* Reset: POR */
+#define I40E_GLNVM_ULD_PCIER_DONE_SHIFT 0
+#define I40E_GLNVM_ULD_PCIER_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_PCIER_DONE_SHIFT)
+#define I40E_GLNVM_ULD_PCIER_DONE_1_SHIFT 1
+#define I40E_GLNVM_ULD_PCIER_DONE_1_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_PCIER_DONE_1_SHIFT)
+#define I40E_GLNVM_ULD_CORER_DONE_SHIFT 3
+#define I40E_GLNVM_ULD_CORER_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_CORER_DONE_SHIFT)
+#define I40E_GLNVM_ULD_GLOBR_DONE_SHIFT 4
+#define I40E_GLNVM_ULD_GLOBR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_GLOBR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_POR_DONE_SHIFT 5
+#define I40E_GLNVM_ULD_POR_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_POR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_POR_DONE_1_SHIFT 8
+#define I40E_GLNVM_ULD_POR_DONE_1_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_POR_DONE_1_SHIFT)
+#define I40E_GLNVM_ULD_PCIER_DONE_2_SHIFT 9
+#define I40E_GLNVM_ULD_PCIER_DONE_2_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_PCIER_DONE_2_SHIFT)
+#define I40E_GLNVM_ULD_PE_DONE_SHIFT 10
+#define I40E_GLNVM_ULD_PE_DONE_MASK I40E_MASK(0x1, I40E_GLNVM_ULD_PE_DONE_SHIFT)
+#define I40E_GLNVM_ULT 0x000B6154 /* Reset: POR */
+#define I40E_GLNVM_ULT_CONF_PCIR_AE_SHIFT 0
+#define I40E_GLNVM_ULT_CONF_PCIR_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_PCIR_AE_SHIFT)
+#define I40E_GLNVM_ULT_CONF_PCIRTL_AE_SHIFT 1
+#define I40E_GLNVM_ULT_CONF_PCIRTL_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_PCIRTL_AE_SHIFT)
+#define I40E_GLNVM_ULT_RESERVED_1_SHIFT 2
+#define I40E_GLNVM_ULT_RESERVED_1_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_RESERVED_1_SHIFT)
+#define I40E_GLNVM_ULT_CONF_CORE_AE_SHIFT 3
+#define I40E_GLNVM_ULT_CONF_CORE_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_CORE_AE_SHIFT)
+#define I40E_GLNVM_ULT_CONF_GLOBAL_AE_SHIFT 4
+#define I40E_GLNVM_ULT_CONF_GLOBAL_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_GLOBAL_AE_SHIFT)
+#define I40E_GLNVM_ULT_CONF_POR_AE_SHIFT 5
+#define I40E_GLNVM_ULT_CONF_POR_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_POR_AE_SHIFT)
+#define I40E_GLNVM_ULT_RESERVED_2_SHIFT 6
+#define I40E_GLNVM_ULT_RESERVED_2_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_RESERVED_2_SHIFT)
+#define I40E_GLNVM_ULT_RESERVED_3_SHIFT 7
+#define I40E_GLNVM_ULT_RESERVED_3_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_RESERVED_3_SHIFT)
+#define I40E_GLNVM_ULT_CONF_EMP_AE_SHIFT 8
+#define I40E_GLNVM_ULT_CONF_EMP_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_EMP_AE_SHIFT)
+#define I40E_GLNVM_ULT_CONF_PCIALT_AE_SHIFT 9
+#define I40E_GLNVM_ULT_CONF_PCIALT_AE_MASK I40E_MASK(0x1, I40E_GLNVM_ULT_CONF_PCIALT_AE_SHIFT)
+#define I40E_GLNVM_ULT_RESERVED_4_SHIFT 10
+#define I40E_GLNVM_ULT_RESERVED_4_MASK I40E_MASK(0x3FFFFF, I40E_GLNVM_ULT_RESERVED_4_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT 0x000B615C /* Reset: POR */
+#define I40E_MEM_INIT_DONE_STAT_CMLAN_MEM_INIT_DONE_SHIFT 0
+#define I40E_MEM_INIT_DONE_STAT_CMLAN_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_CMLAN_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_PMAT_MEM_INIT_DONE_SHIFT 1
+#define I40E_MEM_INIT_DONE_STAT_PMAT_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_PMAT_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_RCU_MEM_INIT_DONE_SHIFT 2
+#define I40E_MEM_INIT_DONE_STAT_RCU_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RCU_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_TDPU_MEM_INIT_DONE_SHIFT 3
+#define I40E_MEM_INIT_DONE_STAT_TDPU_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TDPU_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_TLAN_MEM_INIT_DONE_SHIFT 4
+#define I40E_MEM_INIT_DONE_STAT_TLAN_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TLAN_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_RLAN_MEM_INIT_DONE_SHIFT 5
+#define I40E_MEM_INIT_DONE_STAT_RLAN_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RLAN_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_RDPU_MEM_INIT_DONE_SHIFT 6
+#define I40E_MEM_INIT_DONE_STAT_RDPU_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RDPU_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_PPRS_MEM_INIT_DONE_SHIFT 7
+#define I40E_MEM_INIT_DONE_STAT_PPRS_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_PPRS_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_RPB_MEM_INIT_DONE_SHIFT 8
+#define I40E_MEM_INIT_DONE_STAT_RPB_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RPB_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_TPB_MEM_INIT_DONE_SHIFT 9
+#define I40E_MEM_INIT_DONE_STAT_TPB_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TPB_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_FOC_MEM_INIT_DONE_SHIFT 10
+#define I40E_MEM_INIT_DONE_STAT_FOC_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_FOC_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_TSCD_MEM_INIT_DONE_SHIFT 11
+#define I40E_MEM_INIT_DONE_STAT_TSCD_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TSCD_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_TCB_MEM_INIT_DONE_SHIFT 12
+#define I40E_MEM_INIT_DONE_STAT_TCB_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_TCB_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_RCB_MEM_INIT_DONE_SHIFT 13
+#define I40E_MEM_INIT_DONE_STAT_RCB_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_RCB_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_WUC_MEM_INIT_DONE_SHIFT 14
+#define I40E_MEM_INIT_DONE_STAT_WUC_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_WUC_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_STAT_MEM_INIT_DONE_SHIFT 15
+#define I40E_MEM_INIT_DONE_STAT_STAT_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_STAT_MEM_INIT_DONE_SHIFT)
+#define I40E_MEM_INIT_DONE_STAT_ITR_MEM_INIT_DONE_SHIFT 16
+#define I40E_MEM_INIT_DONE_STAT_ITR_MEM_INIT_DONE_MASK I40E_MASK(0x1, I40E_MEM_INIT_DONE_STAT_ITR_MEM_INIT_DONE_SHIFT)
+#define I40E_MNGSB_DADD 0x000B7030 /* Reset: POR */
+#define I40E_MNGSB_DADD_ADDR_SHIFT 0
+#define I40E_MNGSB_DADD_ADDR_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_DADD_ADDR_SHIFT)
+#define I40E_MNGSB_DCNT 0x000B7034 /* Reset: POR */
+#define I40E_MNGSB_DCNT_BYTE_CNT_SHIFT 0
+#define I40E_MNGSB_DCNT_BYTE_CNT_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_DCNT_BYTE_CNT_SHIFT)
+#define I40E_MNGSB_MSGCTL 0x000B7020 /* Reset: POR */
+#define I40E_MNGSB_MSGCTL_HDR_DWS_SHIFT 0
+#define I40E_MNGSB_MSGCTL_HDR_DWS_MASK I40E_MASK(0x3, I40E_MNGSB_MSGCTL_HDR_DWS_SHIFT)
+#define I40E_MNGSB_MSGCTL_EXP_RDW_SHIFT 8
+#define I40E_MNGSB_MSGCTL_EXP_RDW_MASK I40E_MASK(0x1FF, I40E_MNGSB_MSGCTL_EXP_RDW_SHIFT)
+#define I40E_MNGSB_MSGCTL_MSG_MODE_SHIFT 26
+#define I40E_MNGSB_MSGCTL_MSG_MODE_MASK I40E_MASK(0x3, I40E_MNGSB_MSGCTL_MSG_MODE_SHIFT)
+#define I40E_MNGSB_MSGCTL_TOKEN_MODE_SHIFT 28
+#define I40E_MNGSB_MSGCTL_TOKEN_MODE_MASK I40E_MASK(0x3, I40E_MNGSB_MSGCTL_TOKEN_MODE_SHIFT)
+#define I40E_MNGSB_MSGCTL_BARCLR_SHIFT 30
+#define I40E_MNGSB_MSGCTL_BARCLR_MASK I40E_MASK(0x1, I40E_MNGSB_MSGCTL_BARCLR_SHIFT)
+#define I40E_MNGSB_MSGCTL_CMDV_SHIFT 31
+#define I40E_MNGSB_MSGCTL_CMDV_MASK I40E_MASK(0x1, I40E_MNGSB_MSGCTL_CMDV_SHIFT)
+#define I40E_MNGSB_RDATA 0x000B7300 /* Reset: POR */
+#define I40E_MNGSB_RDATA_DATA_SHIFT 0
+#define I40E_MNGSB_RDATA_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_RDATA_DATA_SHIFT)
+#define I40E_MNGSB_RHDR0 0x000B72FC /* Reset: POR */
+#define I40E_MNGSB_RHDR0_DESTINATION_SHIFT 0
+#define I40E_MNGSB_RHDR0_DESTINATION_MASK I40E_MASK(0xFF, I40E_MNGSB_RHDR0_DESTINATION_SHIFT)
+#define I40E_MNGSB_RHDR0_SOURCE_SHIFT 8
+#define I40E_MNGSB_RHDR0_SOURCE_MASK I40E_MASK(0xFF, I40E_MNGSB_RHDR0_SOURCE_SHIFT)
+#define I40E_MNGSB_RHDR0_OPCODE_SHIFT 16
+#define I40E_MNGSB_RHDR0_OPCODE_MASK I40E_MASK(0xFF, I40E_MNGSB_RHDR0_OPCODE_SHIFT)
+#define I40E_MNGSB_RHDR0_TAG_SHIFT 24
+#define I40E_MNGSB_RHDR0_TAG_MASK I40E_MASK(0x7, I40E_MNGSB_RHDR0_TAG_SHIFT)
+#define I40E_MNGSB_RHDR0_RESPONSE_SHIFT 27
+#define I40E_MNGSB_RHDR0_RESPONSE_MASK I40E_MASK(0x7, I40E_MNGSB_RHDR0_RESPONSE_SHIFT)
+#define I40E_MNGSB_RHDR0_EH_SHIFT 31
+#define I40E_MNGSB_RHDR0_EH_MASK I40E_MASK(0x1, I40E_MNGSB_RHDR0_EH_SHIFT)
+#define I40E_MNGSB_RSPCTL 0x000B7024 /* Reset: POR */
+#define I40E_MNGSB_RSPCTL_DMA_MSG_DWORDS_SHIFT 0
+#define I40E_MNGSB_RSPCTL_DMA_MSG_DWORDS_MASK I40E_MASK(0x1FF, I40E_MNGSB_RSPCTL_DMA_MSG_DWORDS_SHIFT)
+#define I40E_MNGSB_RSPCTL_RSP_MODE_SHIFT 26
+#define I40E_MNGSB_RSPCTL_RSP_MODE_MASK I40E_MASK(0x3, I40E_MNGSB_RSPCTL_RSP_MODE_SHIFT)
+#define I40E_MNGSB_RSPCTL_RSP_BAD_LEN_SHIFT 30
+#define I40E_MNGSB_RSPCTL_RSP_BAD_LEN_MASK I40E_MASK(0x1, I40E_MNGSB_RSPCTL_RSP_BAD_LEN_SHIFT)
+#define I40E_MNGSB_RSPCTL_RSP_ERR_SHIFT 31
+#define I40E_MNGSB_RSPCTL_RSP_ERR_MASK I40E_MASK(0x1, I40E_MNGSB_RSPCTL_RSP_ERR_SHIFT)
+#define I40E_MNGSB_WDATA 0x000B7100 /* Reset: POR */
+#define I40E_MNGSB_WDATA_DATA_SHIFT 0
+#define I40E_MNGSB_WDATA_DATA_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_WDATA_DATA_SHIFT)
+#define I40E_MNGSB_WHDR0 0x000B70F4 /* Reset: POR */
+#define I40E_MNGSB_WHDR0_RAW_DEST_SHIFT 0
+#define I40E_MNGSB_WHDR0_RAW_DEST_MASK I40E_MASK(0xFF, I40E_MNGSB_WHDR0_RAW_DEST_SHIFT)
+#define I40E_MNGSB_WHDR0_DEST_SEL_SHIFT 12
+#define I40E_MNGSB_WHDR0_DEST_SEL_MASK I40E_MASK(0xF, I40E_MNGSB_WHDR0_DEST_SEL_SHIFT)
+#define I40E_MNGSB_WHDR0_OPCODE_SEL_SHIFT 16
+#define I40E_MNGSB_WHDR0_OPCODE_SEL_MASK I40E_MASK(0xFF, I40E_MNGSB_WHDR0_OPCODE_SEL_SHIFT)
+#define I40E_MNGSB_WHDR0_TAG_SHIFT 24
+#define I40E_MNGSB_WHDR0_TAG_MASK I40E_MASK(0x7F, I40E_MNGSB_WHDR0_TAG_SHIFT)
+#define I40E_MNGSB_WHDR1 0x000B70F8 /* Reset: POR */
+#define I40E_MNGSB_WHDR1_ADDR_SHIFT 0
+#define I40E_MNGSB_WHDR1_ADDR_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_WHDR1_ADDR_SHIFT)
+#define I40E_MNGSB_WHDR2 0x000B70FC /* Reset: POR */
+#define I40E_MNGSB_WHDR2_LENGTH_SHIFT 0
+#define I40E_MNGSB_WHDR2_LENGTH_MASK I40E_MASK(0xFFFFFFFF, I40E_MNGSB_WHDR2_LENGTH_SHIFT)
+
+#define I40E_GLPCI_CAPSUP_WAKUP_EN_SHIFT 21
+#define I40E_GLPCI_CAPSUP_WAKUP_EN_MASK I40E_MASK(0x1, I40E_GLPCI_CAPSUP_WAKUP_EN_SHIFT)
+
+#define I40E_GLPCI_CUR_CLNT_COMMON 0x0009CA18 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_CLNT_COMMON_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_CLNT_COMMON_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_CLNT_COMMON_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_CLNT_COMMON_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_CLNT_COMMON_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_CLNT_COMMON_OSR_SHIFT)
+#define I40E_GLPCI_CUR_CLNT_PIPEMON 0x0009CA20 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_CLNT_PIPEMON_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_CLNT_PIPEMON_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_CLNT_PIPEMON_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_MNG_ALWD 0x0009c514 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_MNG_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_MNG_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_MNG_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_MNG_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_MNG_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_MNG_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_MNG_RSVD 0x0009c594 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_MNG_RSVD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_MNG_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_MNG_RSVD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_MNG_RSVD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_MNG_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_MNG_RSVD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_PMAT_ALWD 0x0009c510 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_PMAT_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_PMAT_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_PMAT_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_PMAT_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_PMAT_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_PMAT_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_PMAT_RSVD 0x0009c590 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_PMAT_RSVD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_PMAT_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_PMAT_RSVD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_PMAT_RSVD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_PMAT_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_PMAT_RSVD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_RLAN_ALWD 0x0009c500 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_RLAN_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_RLAN_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RLAN_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_RLAN_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_RLAN_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RLAN_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_RLAN_RSVD 0x0009c580 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_RLAN_RSVD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_RLAN_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RLAN_RSVD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_RLAN_RSVD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_RLAN_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RLAN_RSVD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_RXPE_ALWD 0x0009c508 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_RXPE_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_RXPE_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RXPE_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_RXPE_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_RXPE_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RXPE_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_RXPE_RSVD 0x0009c588 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_RXPE_RSVD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_RXPE_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RXPE_RSVD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_RXPE_RSVD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_RXPE_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_RXPE_RSVD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_TDPU_ALWD 0x0009c518 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_TDPU_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_TDPU_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TDPU_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_TDPU_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_TDPU_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TDPU_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_TDPU_RSVD 0x0009c598 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_TDPU_RSVD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_TDPU_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TDPU_RSVD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_TDPU_RSVD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_TDPU_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TDPU_RSVD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_TLAN_ALWD 0x0009c504 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_TLAN_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_TLAN_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TLAN_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_TLAN_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_TLAN_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TLAN_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_TLAN_RSVD 0x0009c584 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_TLAN_RSVD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_TLAN_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TLAN_RSVD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_TLAN_RSVD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_TLAN_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TLAN_RSVD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_TXPE_ALWD 0x0009c50C /* Reset: PCIR */
+#define I40E_GLPCI_CUR_TXPE_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_TXPE_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TXPE_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_TXPE_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_TXPE_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TXPE_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_TXPE_RSVD 0x0009c58c /* Reset: PCIR */
+#define I40E_GLPCI_CUR_TXPE_RSVD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_TXPE_RSVD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TXPE_RSVD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_TXPE_RSVD_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_TXPE_RSVD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_TXPE_RSVD_OSR_SHIFT)
+#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON 0x0009CA28 /* Reset: PCIR */
+#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_WATMK_CLNT_COMMON_DATA_LINES_SHIFT)
+#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON_OSR_SHIFT 16
+#define I40E_GLPCI_CUR_WATMK_CLNT_COMMON_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_CUR_WATMK_CLNT_COMMON_OSR_SHIFT)
+
+#define I40E_GLPCI_LBARCTRL_PE_DB_SIZE_SHIFT 4
+#define I40E_GLPCI_LBARCTRL_PE_DB_SIZE_MASK I40E_MASK(0x3, I40E_GLPCI_LBARCTRL_PE_DB_SIZE_SHIFT)
+#define I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_SHIFT 10
+#define I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_MASK I40E_MASK(0x1, I40E_GLPCI_LBARCTRL_VF_PE_DB_SIZE_SHIFT)
+#define I40E_GLPCI_NPQ_CFG 0x0009CA00 /* Reset: PCIR */
+#define I40E_GLPCI_NPQ_CFG_EXTEND_TO_SHIFT 0
+#define I40E_GLPCI_NPQ_CFG_EXTEND_TO_MASK I40E_MASK(0x1, I40E_GLPCI_NPQ_CFG_EXTEND_TO_SHIFT)
+#define I40E_GLPCI_NPQ_CFG_SMALL_TO_SHIFT 1
+#define I40E_GLPCI_NPQ_CFG_SMALL_TO_MASK I40E_MASK(0x1, I40E_GLPCI_NPQ_CFG_SMALL_TO_SHIFT)
+#define I40E_GLPCI_NPQ_CFG_WEIGHT_AVG_SHIFT 2
+#define I40E_GLPCI_NPQ_CFG_WEIGHT_AVG_MASK I40E_MASK(0xF, I40E_GLPCI_NPQ_CFG_WEIGHT_AVG_SHIFT)
+#define I40E_GLPCI_NPQ_CFG_NPQ_SPARE_SHIFT 6
+#define I40E_GLPCI_NPQ_CFG_NPQ_SPARE_MASK I40E_MASK(0x3FF, I40E_GLPCI_NPQ_CFG_NPQ_SPARE_SHIFT)
+#define I40E_GLPCI_NPQ_CFG_NPQ_ERR_STAT_SHIFT 16
+#define I40E_GLPCI_NPQ_CFG_NPQ_ERR_STAT_MASK I40E_MASK(0xF, I40E_GLPCI_NPQ_CFG_NPQ_ERR_STAT_SHIFT)
+#define I40E_GLPCI_WATMK_CLNT_PIPEMON 0x0009CA30 /* Reset: PCIR */
+#define I40E_GLPCI_WATMK_CLNT_PIPEMON_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_WATMK_CLNT_PIPEMON_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_CLNT_PIPEMON_DATA_LINES_SHIFT)
+#define I40E_GLPCI_WATMK_MNG_ALWD 0x0009CB14 /* Reset: PCIR */
+#define I40E_GLPCI_WATMK_MNG_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_WATMK_MNG_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_MNG_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_WATMK_MNG_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_WATMK_MNG_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_MNG_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_WATMK_PMAT_ALWD 0x0009CB10 /* Reset: PCIR */
+#define I40E_GLPCI_WATMK_PMAT_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_WATMK_PMAT_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_PMAT_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_WATMK_PMAT_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_WATMK_PMAT_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_PMAT_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_WATMK_RLAN_ALWD 0x0009CB00 /* Reset: PCIR */
+#define I40E_GLPCI_WATMK_RLAN_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_WATMK_RLAN_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_RLAN_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_WATMK_RLAN_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_WATMK_RLAN_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_RLAN_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_WATMK_RXPE_ALWD 0x0009CB08 /* Reset: PCIR */
+#define I40E_GLPCI_WATMK_RXPE_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_WATMK_RXPE_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_RXPE_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_WATMK_RXPE_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_WATMK_RXPE_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_RXPE_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_WATMK_TLAN_ALWD 0x0009CB04 /* Reset: PCIR */
+#define I40E_GLPCI_WATMK_TLAN_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_WATMK_TLAN_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TLAN_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_WATMK_TLAN_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_WATMK_TLAN_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TLAN_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_WATMK_TPDU_ALWD 0x0009CB18 /* Reset: PCIR */
+#define I40E_GLPCI_WATMK_TPDU_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_WATMK_TPDU_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TPDU_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_WATMK_TPDU_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_WATMK_TPDU_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TPDU_ALWD_OSR_SHIFT)
+#define I40E_GLPCI_WATMK_TXPE_ALWD 0x0009CB0c /* Reset: PCIR */
+#define I40E_GLPCI_WATMK_TXPE_ALWD_DATA_LINES_SHIFT 0
+#define I40E_GLPCI_WATMK_TXPE_ALWD_DATA_LINES_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TXPE_ALWD_DATA_LINES_SHIFT)
+#define I40E_GLPCI_WATMK_TXPE_ALWD_OSR_SHIFT 16
+#define I40E_GLPCI_WATMK_TXPE_ALWD_OSR_MASK I40E_MASK(0xFFFF, I40E_GLPCI_WATMK_TXPE_ALWD_OSR_SHIFT)
+#define I40E_GLPE_CPUSTATUS0 0x0000D040 /* Reset: PE_CORER */
+#define I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_SHIFT 0
+#define I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPE_CPUSTATUS0_PECPUSTATUS0_SHIFT)
+#define I40E_GLPE_CPUSTATUS1 0x0000D044 /* Reset: PE_CORER */
+#define I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_SHIFT 0
+#define I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPE_CPUSTATUS1_PECPUSTATUS1_SHIFT)
+#define I40E_GLPE_CPUSTATUS2 0x0000D048 /* Reset: PE_CORER */
+#define I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_SHIFT 0
+#define I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPE_CPUSTATUS2_PECPUSTATUS2_SHIFT)
+#define I40E_GLPE_CPUTRIG0 0x0000D060 /* Reset: PE_CORER */
+#define I40E_GLPE_CPUTRIG0_PECPUTRIG0_SHIFT 0
+#define I40E_GLPE_CPUTRIG0_PECPUTRIG0_MASK I40E_MASK(0xFFFF, I40E_GLPE_CPUTRIG0_PECPUTRIG0_SHIFT)
+#define I40E_GLPE_CPUTRIG0_TEPREQUEST0_SHIFT 17
+#define I40E_GLPE_CPUTRIG0_TEPREQUEST0_MASK I40E_MASK(0x1, I40E_GLPE_CPUTRIG0_TEPREQUEST0_SHIFT)
+#define I40E_GLPE_CPUTRIG0_OOPREQUEST0_SHIFT 18
+#define I40E_GLPE_CPUTRIG0_OOPREQUEST0_MASK I40E_MASK(0x1, I40E_GLPE_CPUTRIG0_OOPREQUEST0_SHIFT)
+#define I40E_GLPE_DUAL40_RUPM 0x0000DA04 /* Reset: PE_CORER */
+#define I40E_GLPE_DUAL40_RUPM_DUAL_40G_MODE_SHIFT 0
+#define I40E_GLPE_DUAL40_RUPM_DUAL_40G_MODE_MASK I40E_MASK(0x1, I40E_GLPE_DUAL40_RUPM_DUAL_40G_MODE_SHIFT)
+#define I40E_GLPE_PFAEQEDROPCNT(_i) (0x00131440 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLPE_PFAEQEDROPCNT_MAX_INDEX 15
+#define I40E_GLPE_PFAEQEDROPCNT_AEQEDROPCNT_SHIFT 0
+#define I40E_GLPE_PFAEQEDROPCNT_AEQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_PFAEQEDROPCNT_AEQEDROPCNT_SHIFT)
+#define I40E_GLPE_PFCEQEDROPCNT(_i) (0x001313C0 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLPE_PFCEQEDROPCNT_MAX_INDEX 15
+#define I40E_GLPE_PFCEQEDROPCNT_CEQEDROPCNT_SHIFT 0
+#define I40E_GLPE_PFCEQEDROPCNT_CEQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_PFCEQEDROPCNT_CEQEDROPCNT_SHIFT)
+#define I40E_GLPE_PFCQEDROPCNT(_i) (0x00131340 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define I40E_GLPE_PFCQEDROPCNT_MAX_INDEX 15
+#define I40E_GLPE_PFCQEDROPCNT_CQEDROPCNT_SHIFT 0
+#define I40E_GLPE_PFCQEDROPCNT_CQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_PFCQEDROPCNT_CQEDROPCNT_SHIFT)
+#define I40E_GLPE_RUPM_CQPPOOL 0x0000DACC /* Reset: PE_CORER */
+#define I40E_GLPE_RUPM_CQPPOOL_CQPSPADS_SHIFT 0
+#define I40E_GLPE_RUPM_CQPPOOL_CQPSPADS_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_CQPPOOL_CQPSPADS_SHIFT)
+#define I40E_GLPE_RUPM_FLRPOOL 0x0000DAC4 /* Reset: PE_CORER */
+#define I40E_GLPE_RUPM_FLRPOOL_FLRSPADS_SHIFT 0
+#define I40E_GLPE_RUPM_FLRPOOL_FLRSPADS_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_FLRPOOL_FLRSPADS_SHIFT)
+#define I40E_GLPE_RUPM_GCTL 0x0000DA00 /* Reset: PE_CORER */
+#define I40E_GLPE_RUPM_GCTL_ALLOFFTH_SHIFT 0
+#define I40E_GLPE_RUPM_GCTL_ALLOFFTH_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_GCTL_ALLOFFTH_SHIFT)
+#define I40E_GLPE_RUPM_GCTL_RUPM_P0_DIS_SHIFT 26
+#define I40E_GLPE_RUPM_GCTL_RUPM_P0_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_P0_DIS_SHIFT)
+#define I40E_GLPE_RUPM_GCTL_RUPM_P1_DIS_SHIFT 27
+#define I40E_GLPE_RUPM_GCTL_RUPM_P1_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_P1_DIS_SHIFT)
+#define I40E_GLPE_RUPM_GCTL_RUPM_P2_DIS_SHIFT 28
+#define I40E_GLPE_RUPM_GCTL_RUPM_P2_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_P2_DIS_SHIFT)
+#define I40E_GLPE_RUPM_GCTL_RUPM_P3_DIS_SHIFT 29
+#define I40E_GLPE_RUPM_GCTL_RUPM_P3_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_P3_DIS_SHIFT)
+#define I40E_GLPE_RUPM_GCTL_RUPM_DIS_SHIFT 30
+#define I40E_GLPE_RUPM_GCTL_RUPM_DIS_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_RUPM_DIS_SHIFT)
+#define I40E_GLPE_RUPM_GCTL_SWLB_MODE_SHIFT 31
+#define I40E_GLPE_RUPM_GCTL_SWLB_MODE_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_GCTL_SWLB_MODE_SHIFT)
+#define I40E_GLPE_RUPM_PTXPOOL 0x0000DAC8 /* Reset: PE_CORER */
+#define I40E_GLPE_RUPM_PTXPOOL_PTXSPADS_SHIFT 0
+#define I40E_GLPE_RUPM_PTXPOOL_PTXSPADS_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_PTXPOOL_PTXSPADS_SHIFT)
+#define I40E_GLPE_RUPM_PUSHPOOL 0x0000DAC0 /* Reset: PE_CORER */
+#define I40E_GLPE_RUPM_PUSHPOOL_PUSHSPADS_SHIFT 0
+#define I40E_GLPE_RUPM_PUSHPOOL_PUSHSPADS_MASK I40E_MASK(0xFF, I40E_GLPE_RUPM_PUSHPOOL_PUSHSPADS_SHIFT)
+#define I40E_GLPE_RUPM_TXHOST_EN 0x0000DA08 /* Reset: PE_CORER */
+#define I40E_GLPE_RUPM_TXHOST_EN_TXHOST_EN_SHIFT 0
+#define I40E_GLPE_RUPM_TXHOST_EN_TXHOST_EN_MASK I40E_MASK(0x1, I40E_GLPE_RUPM_TXHOST_EN_TXHOST_EN_SHIFT)
+#define I40E_GLPE_VFAEQEDROPCNT(_i) (0x00132540 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLPE_VFAEQEDROPCNT_MAX_INDEX 31
+#define I40E_GLPE_VFAEQEDROPCNT_AEQEDROPCNT_SHIFT 0
+#define I40E_GLPE_VFAEQEDROPCNT_AEQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFAEQEDROPCNT_AEQEDROPCNT_SHIFT)
+#define I40E_GLPE_VFCEQEDROPCNT(_i) (0x00132440 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLPE_VFCEQEDROPCNT_MAX_INDEX 31
+#define I40E_GLPE_VFCEQEDROPCNT_CEQEDROPCNT_SHIFT 0
+#define I40E_GLPE_VFCEQEDROPCNT_CEQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFCEQEDROPCNT_CEQEDROPCNT_SHIFT)
+#define I40E_GLPE_VFCQEDROPCNT(_i) (0x00132340 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */
+#define I40E_GLPE_VFCQEDROPCNT_MAX_INDEX 31
+#define I40E_GLPE_VFCQEDROPCNT_CQEDROPCNT_SHIFT 0
+#define I40E_GLPE_VFCQEDROPCNT_CQEDROPCNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFCQEDROPCNT_CQEDROPCNT_SHIFT)
+#define I40E_GLPE_VFFLMOBJCTRL(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPE_VFFLMOBJCTRL_MAX_INDEX 31
+#define I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT 0
+#define I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_MASK I40E_MASK(0x7, I40E_GLPE_VFFLMOBJCTRL_XMIT_BLOCKSIZE_SHIFT)
+#define I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT 8
+#define I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_MASK I40E_MASK(0x7, I40E_GLPE_VFFLMOBJCTRL_Q1_BLOCKSIZE_SHIFT)
+#define I40E_GLPE_VFFLMQ1ALLOCERR(_i) (0x0000C700 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPE_VFFLMQ1ALLOCERR_MAX_INDEX 31
+#define I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_SHIFT 0
+#define I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFFLMQ1ALLOCERR_ERROR_COUNT_SHIFT)
+#define I40E_GLPE_VFFLMXMITALLOCERR(_i) (0x0000C600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPE_VFFLMXMITALLOCERR_MAX_INDEX 31
+#define I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_SHIFT 0
+#define I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_MASK I40E_MASK(0xFFFF, I40E_GLPE_VFFLMXMITALLOCERR_ERROR_COUNT_SHIFT)
+#define I40E_GLPE_VFUDACTRL(_i) (0x0000C000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPE_VFUDACTRL_MAX_INDEX 31
+#define I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_SHIFT 0
+#define I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_IPV4MCFRAGRESBP_SHIFT)
+#define I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_SHIFT 1
+#define I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_IPV4UCFRAGRESBP_SHIFT)
+#define I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_SHIFT 2
+#define I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_IPV6MCFRAGRESBP_SHIFT)
+#define I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_SHIFT 3
+#define I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_IPV6UCFRAGRESBP_SHIFT)
+#define I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_SHIFT 4
+#define I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_MASK I40E_MASK(0x1, I40E_GLPE_VFUDACTRL_UDPMCFRAGRESFAIL_SHIFT)
+#define I40E_GLPE_VFUDAUCFBQPN(_i) (0x0000C100 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPE_VFUDAUCFBQPN_MAX_INDEX 31
+#define I40E_GLPE_VFUDAUCFBQPN_QPN_SHIFT 0
+#define I40E_GLPE_VFUDAUCFBQPN_QPN_MASK I40E_MASK(0x3FFFF, I40E_GLPE_VFUDAUCFBQPN_QPN_SHIFT)
+#define I40E_GLPE_VFUDAUCFBQPN_VALID_SHIFT 31
+#define I40E_GLPE_VFUDAUCFBQPN_VALID_MASK I40E_MASK(0x1, I40E_GLPE_VFUDAUCFBQPN_VALID_SHIFT)
+#define I40E_PFPE_AEQALLOC 0x00131180 /* Reset: PFR */
+#define I40E_PFPE_AEQALLOC_AECOUNT_SHIFT 0
+#define I40E_PFPE_AEQALLOC_AECOUNT_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPE_AEQALLOC_AECOUNT_SHIFT)
+#define I40E_PFPE_CCQPHIGH 0x00008200 /* Reset: PFR */
+#define I40E_PFPE_CCQPHIGH_PECCQPHIGH_SHIFT 0
+#define I40E_PFPE_CCQPHIGH_PECCQPHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPE_CCQPHIGH_PECCQPHIGH_SHIFT)
+#define I40E_PFPE_CCQPLOW 0x00008180 /* Reset: PFR */
+#define I40E_PFPE_CCQPLOW_PECCQPLOW_SHIFT 0
+#define I40E_PFPE_CCQPLOW_PECCQPLOW_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPE_CCQPLOW_PECCQPLOW_SHIFT)
+#define I40E_PFPE_CCQPSTATUS 0x00008100 /* Reset: PFR */
+#define I40E_PFPE_CCQPSTATUS_CCQP_DONE_SHIFT 0
+#define I40E_PFPE_CCQPSTATUS_CCQP_DONE_MASK I40E_MASK(0x1, I40E_PFPE_CCQPSTATUS_CCQP_DONE_SHIFT)
+#define I40E_PFPE_CCQPSTATUS_HMC_PROFILE_SHIFT 4
+#define I40E_PFPE_CCQPSTATUS_HMC_PROFILE_MASK I40E_MASK(0x7, I40E_PFPE_CCQPSTATUS_HMC_PROFILE_SHIFT)
+#define I40E_PFPE_CCQPSTATUS_RDMA_EN_VFS_SHIFT 16
+#define I40E_PFPE_CCQPSTATUS_RDMA_EN_VFS_MASK I40E_MASK(0x3F, I40E_PFPE_CCQPSTATUS_RDMA_EN_VFS_SHIFT)
+#define I40E_PFPE_CCQPSTATUS_CCQP_ERR_SHIFT 31
+#define I40E_PFPE_CCQPSTATUS_CCQP_ERR_MASK I40E_MASK(0x1, I40E_PFPE_CCQPSTATUS_CCQP_ERR_SHIFT)
+#define I40E_PFPE_CQACK 0x00131100 /* Reset: PFR */
+#define I40E_PFPE_CQACK_PECQID_SHIFT 0
+#define I40E_PFPE_CQACK_PECQID_MASK I40E_MASK(0x1FFFF, I40E_PFPE_CQACK_PECQID_SHIFT)
+#define I40E_PFPE_CQARM 0x00131080 /* Reset: PFR */
+#define I40E_PFPE_CQARM_PECQID_SHIFT 0
+#define I40E_PFPE_CQARM_PECQID_MASK I40E_MASK(0x1FFFF, I40E_PFPE_CQARM_PECQID_SHIFT)
+#define I40E_PFPE_CQPDB 0x00008000 /* Reset: PFR */
+#define I40E_PFPE_CQPDB_WQHEAD_SHIFT 0
+#define I40E_PFPE_CQPDB_WQHEAD_MASK I40E_MASK(0x7FF, I40E_PFPE_CQPDB_WQHEAD_SHIFT)
+#define I40E_PFPE_CQPERRCODES 0x00008880 /* Reset: PFR */
+#define I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT 0
+#define I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_MASK I40E_MASK(0xFFFF, I40E_PFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT)
+#define I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT 16
+#define I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_MASK I40E_MASK(0xFFFF, I40E_PFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT)
+#define I40E_PFPE_CQPTAIL 0x00008080 /* Reset: PFR */
+#define I40E_PFPE_CQPTAIL_WQTAIL_SHIFT 0
+#define I40E_PFPE_CQPTAIL_WQTAIL_MASK I40E_MASK(0x7FF, I40E_PFPE_CQPTAIL_WQTAIL_SHIFT)
+#define I40E_PFPE_CQPTAIL_CQP_OP_ERR_SHIFT 31
+#define I40E_PFPE_CQPTAIL_CQP_OP_ERR_MASK I40E_MASK(0x1, I40E_PFPE_CQPTAIL_CQP_OP_ERR_SHIFT)
+#define I40E_PFPE_FLMQ1ALLOCERR 0x00008980 /* Reset: PFR */
+#define I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_SHIFT 0
+#define I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_MASK I40E_MASK(0xFFFF, I40E_PFPE_FLMQ1ALLOCERR_ERROR_COUNT_SHIFT)
+#define I40E_PFPE_FLMXMITALLOCERR 0x00008900 /* Reset: PFR */
+#define I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_SHIFT 0
+#define I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_MASK I40E_MASK(0xFFFF, I40E_PFPE_FLMXMITALLOCERR_ERROR_COUNT_SHIFT)
+#define I40E_PFPE_IPCONFIG0 0x00008280 /* Reset: PFR */
+#define I40E_PFPE_IPCONFIG0_PEIPID_SHIFT 0
+#define I40E_PFPE_IPCONFIG0_PEIPID_MASK I40E_MASK(0xFFFF, I40E_PFPE_IPCONFIG0_PEIPID_SHIFT)
+#define I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT 16
+#define I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_MASK I40E_MASK(0x1, I40E_PFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT)
+#define I40E_PFPE_MRTEIDXMASK 0x00008600 /* Reset: PFR */
+#define I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT 0
+#define I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_MASK I40E_MASK(0x1F, I40E_PFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT)
+#define I40E_PFPE_RCVUNEXPECTEDERROR 0x00008680 /* Reset: PFR */
+#define I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT 0
+#define I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_MASK I40E_MASK(0xFFFFFF, I40E_PFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT)
+#define I40E_PFPE_TCPNOWTIMER 0x00008580 /* Reset: PFR */
+#define I40E_PFPE_TCPNOWTIMER_TCP_NOW_SHIFT 0
+#define I40E_PFPE_TCPNOWTIMER_TCP_NOW_MASK I40E_MASK(0xFFFFFFFF, I40E_PFPE_TCPNOWTIMER_TCP_NOW_SHIFT)
+#define I40E_PFPE_UDACTRL 0x00008700 /* Reset: PFR */
+#define I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_SHIFT 0
+#define I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_IPV4MCFRAGRESBP_SHIFT)
+#define I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_SHIFT 1
+#define I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_IPV4UCFRAGRESBP_SHIFT)
+#define I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_SHIFT 2
+#define I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_IPV6MCFRAGRESBP_SHIFT)
+#define I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_SHIFT 3
+#define I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_IPV6UCFRAGRESBP_SHIFT)
+#define I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_SHIFT 4
+#define I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_MASK I40E_MASK(0x1, I40E_PFPE_UDACTRL_UDPMCFRAGRESFAIL_SHIFT)
+#define I40E_PFPE_UDAUCFBQPN 0x00008780 /* Reset: PFR */
+#define I40E_PFPE_UDAUCFBQPN_QPN_SHIFT 0
+#define I40E_PFPE_UDAUCFBQPN_QPN_MASK I40E_MASK(0x3FFFF, I40E_PFPE_UDAUCFBQPN_QPN_SHIFT)
+#define I40E_PFPE_UDAUCFBQPN_VALID_SHIFT 31
+#define I40E_PFPE_UDAUCFBQPN_VALID_MASK I40E_MASK(0x1, I40E_PFPE_UDAUCFBQPN_VALID_SHIFT)
+#define I40E_PFPE_WQEALLOC 0x00138C00 /* Reset: PFR */
+#define I40E_PFPE_WQEALLOC_PEQPID_SHIFT 0
+#define I40E_PFPE_WQEALLOC_PEQPID_MASK I40E_MASK(0x3FFFF, I40E_PFPE_WQEALLOC_PEQPID_SHIFT)
+#define I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT 20
+#define I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_MASK I40E_MASK(0xFFF, I40E_PFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT)
+#define I40E_PRTDCB_RLPMC 0x0001F140 /* Reset: PE_CORER */
+#define I40E_PRTDCB_RLPMC_TC2PFC_SHIFT 0
+#define I40E_PRTDCB_RLPMC_TC2PFC_MASK I40E_MASK(0xFF, I40E_PRTDCB_RLPMC_TC2PFC_SHIFT)
+#define I40E_PRTDCB_TCMSTC_RLPM(_i) (0x0001F040 + ((_i) * 32)) /* _i=0...7 */ /* Reset: PE_CORER */
+#define I40E_PRTDCB_TCMSTC_RLPM_MAX_INDEX 7
+#define I40E_PRTDCB_TCMSTC_RLPM_MSTC_SHIFT 0
+#define I40E_PRTDCB_TCMSTC_RLPM_MSTC_MASK I40E_MASK(0xFFFFF, I40E_PRTDCB_TCMSTC_RLPM_MSTC_SHIFT)
+#define I40E_PRTDCB_TCPMC_RLPM 0x0001F1A0 /* Reset: PE_CORER */
+#define I40E_PRTDCB_TCPMC_RLPM_CPM_SHIFT 0
+#define I40E_PRTDCB_TCPMC_RLPM_CPM_MASK I40E_MASK(0x1FFF, I40E_PRTDCB_TCPMC_RLPM_CPM_SHIFT)
+#define I40E_PRTDCB_TCPMC_RLPM_LLTC_SHIFT 13
+#define I40E_PRTDCB_TCPMC_RLPM_LLTC_MASK I40E_MASK(0xFF, I40E_PRTDCB_TCPMC_RLPM_LLTC_SHIFT)
+#define I40E_PRTDCB_TCPMC_RLPM_TCPM_MODE_SHIFT 30
+#define I40E_PRTDCB_TCPMC_RLPM_TCPM_MODE_MASK I40E_MASK(0x1, I40E_PRTDCB_TCPMC_RLPM_TCPM_MODE_SHIFT)
+#define I40E_PRTE_RUPM_TCCNTR03 0x0000DAE0 /* Reset: PE_CORER */
+#define I40E_PRTE_RUPM_TCCNTR03_TC0COUNT_SHIFT 0
+#define I40E_PRTE_RUPM_TCCNTR03_TC0COUNT_MASK I40E_MASK(0xFF, I40E_PRTE_RUPM_TCCNTR03_TC0COUNT_SHIFT)
+#define I40E_PRTE_RUPM_TCCNTR03_TC1COUNT_SHIFT 8
+#define I40E_PRTE_RUPM_TCCNTR03_TC1COUNT_MASK I40E_MASK(0xFF, I40E_PRTE_RUPM_TCCNTR03_TC1COUNT_SHIFT)
+#define I40E_PRTE_RUPM_TCCNTR03_TC2COUNT_SHIFT 16
+#define I40E_PRTE_RUPM_TCCNTR03_TC2COUNT_MASK I40E_MASK(0xFF, I40E_PRTE_RUPM_TCCNTR03_TC2COUNT_SHIFT)
+#define I40E_PRTE_RUPM_TCCNTR03_TC3COUNT_SHIFT 24
+#define I40E_PRTE_RUPM_TCCNTR03_TC3COUNT_MASK I40E_MASK(0xFF, I40E_PRTE_RUPM_TCCNTR03_TC3COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_CNTR 0x0000DB20 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_CNTR_COUNT_SHIFT 0
+#define I40E_PRTPE_RUPM_CNTR_COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_CNTR_COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_CTL 0x0000DA40 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_CTL_LLTC_SHIFT 13
+#define I40E_PRTPE_RUPM_CTL_LLTC_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_CTL_LLTC_SHIFT)
+#define I40E_PRTPE_RUPM_CTL_RUPM_MODE_SHIFT 30
+#define I40E_PRTPE_RUPM_CTL_RUPM_MODE_MASK I40E_MASK(0x1, I40E_PRTPE_RUPM_CTL_RUPM_MODE_SHIFT)
+#define I40E_PRTPE_RUPM_PFCCTL 0x0000DA60 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_PFCCTL_TC2PFC_SHIFT 0
+#define I40E_PRTPE_RUPM_PFCCTL_TC2PFC_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PFCCTL_TC2PFC_SHIFT)
+#define I40E_PRTPE_RUPM_PFCPC 0x0000DA80 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_PFCPC_PORTOFFTH_SHIFT 0
+#define I40E_PRTPE_RUPM_PFCPC_PORTOFFTH_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PFCPC_PORTOFFTH_SHIFT)
+#define I40E_PRTPE_RUPM_PFCTCC 0x0000DAA0 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_PFCTCC_TCOFFTH_SHIFT 0
+#define I40E_PRTPE_RUPM_PFCTCC_TCOFFTH_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PFCTCC_TCOFFTH_SHIFT)
+#define I40E_PRTPE_RUPM_PFCTCC_LL_PRI_TH_SHIFT 16
+#define I40E_PRTPE_RUPM_PFCTCC_LL_PRI_TH_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PFCTCC_LL_PRI_TH_SHIFT)
+#define I40E_PRTPE_RUPM_PFCTCC_LL_PRI_EN_SHIFT 31
+#define I40E_PRTPE_RUPM_PFCTCC_LL_PRI_EN_MASK I40E_MASK(0x1, I40E_PRTPE_RUPM_PFCTCC_LL_PRI_EN_SHIFT)
+#define I40E_PRTPE_RUPM_PTCTCCNTR47 0x0000DB60 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC4COUNT_SHIFT 0
+#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC4COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTCTCCNTR47_TC4COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC5COUNT_SHIFT 8
+#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC5COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTCTCCNTR47_TC5COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC6COUNT_SHIFT 16
+#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC6COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTCTCCNTR47_TC6COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC7COUNT_SHIFT 24
+#define I40E_PRTPE_RUPM_PTCTCCNTR47_TC7COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTCTCCNTR47_TC7COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_PTXTCCNTR03 0x0000DB40 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC0COUNT_SHIFT 0
+#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC0COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTXTCCNTR03_TC0COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC1COUNT_SHIFT 8
+#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC1COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTXTCCNTR03_TC1COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC2COUNT_SHIFT 16
+#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC2COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTXTCCNTR03_TC2COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC3COUNT_SHIFT 24
+#define I40E_PRTPE_RUPM_PTXTCCNTR03_TC3COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_PTXTCCNTR03_TC3COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_TCCNTR47 0x0000DB00 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_TCCNTR47_TC4COUNT_SHIFT 0
+#define I40E_PRTPE_RUPM_TCCNTR47_TC4COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_TCCNTR47_TC4COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_TCCNTR47_TC5COUNT_SHIFT 8
+#define I40E_PRTPE_RUPM_TCCNTR47_TC5COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_TCCNTR47_TC5COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_TCCNTR47_TC6COUNT_SHIFT 16
+#define I40E_PRTPE_RUPM_TCCNTR47_TC6COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_TCCNTR47_TC6COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_TCCNTR47_TC7COUNT_SHIFT 24
+#define I40E_PRTPE_RUPM_TCCNTR47_TC7COUNT_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_TCCNTR47_TC7COUNT_SHIFT)
+#define I40E_PRTPE_RUPM_THRES 0x0000DA20 /* Reset: PE_CORER */
+#define I40E_PRTPE_RUPM_THRES_MINSPADSPERTC_SHIFT 0
+#define I40E_PRTPE_RUPM_THRES_MINSPADSPERTC_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_THRES_MINSPADSPERTC_SHIFT)
+#define I40E_PRTPE_RUPM_THRES_MAXSPADS_SHIFT 8
+#define I40E_PRTPE_RUPM_THRES_MAXSPADS_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_THRES_MAXSPADS_SHIFT)
+#define I40E_PRTPE_RUPM_THRES_MAXSPADSPERTC_SHIFT 16
+#define I40E_PRTPE_RUPM_THRES_MAXSPADSPERTC_MASK I40E_MASK(0xFF, I40E_PRTPE_RUPM_THRES_MAXSPADSPERTC_SHIFT)
+#define I40E_VFPE_AEQALLOC(_VF) (0x00130C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_AEQALLOC_MAX_INDEX 127
+#define I40E_VFPE_AEQALLOC_AECOUNT_SHIFT 0
+#define I40E_VFPE_AEQALLOC_AECOUNT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_AEQALLOC_AECOUNT_SHIFT)
+#define I40E_VFPE_CCQPHIGH(_VF) (0x00001000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_CCQPHIGH_MAX_INDEX 127
+#define I40E_VFPE_CCQPHIGH_PECCQPHIGH_SHIFT 0
+#define I40E_VFPE_CCQPHIGH_PECCQPHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_CCQPHIGH_PECCQPHIGH_SHIFT)
+#define I40E_VFPE_CCQPLOW(_VF) (0x00000C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_CCQPLOW_MAX_INDEX 127
+#define I40E_VFPE_CCQPLOW_PECCQPLOW_SHIFT 0
+#define I40E_VFPE_CCQPLOW_PECCQPLOW_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_CCQPLOW_PECCQPLOW_SHIFT)
+#define I40E_VFPE_CCQPSTATUS(_VF) (0x00000800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_CCQPSTATUS_MAX_INDEX 127
+#define I40E_VFPE_CCQPSTATUS_CCQP_DONE_SHIFT 0
+#define I40E_VFPE_CCQPSTATUS_CCQP_DONE_MASK I40E_MASK(0x1, I40E_VFPE_CCQPSTATUS_CCQP_DONE_SHIFT)
+#define I40E_VFPE_CCQPSTATUS_HMC_PROFILE_SHIFT 4
+#define I40E_VFPE_CCQPSTATUS_HMC_PROFILE_MASK I40E_MASK(0x7, I40E_VFPE_CCQPSTATUS_HMC_PROFILE_SHIFT)
+#define I40E_VFPE_CCQPSTATUS_RDMA_EN_VFS_SHIFT 16
+#define I40E_VFPE_CCQPSTATUS_RDMA_EN_VFS_MASK I40E_MASK(0x3F, I40E_VFPE_CCQPSTATUS_RDMA_EN_VFS_SHIFT)
+#define I40E_VFPE_CCQPSTATUS_CCQP_ERR_SHIFT 31
+#define I40E_VFPE_CCQPSTATUS_CCQP_ERR_MASK I40E_MASK(0x1, I40E_VFPE_CCQPSTATUS_CCQP_ERR_SHIFT)
+#define I40E_VFPE_CQACK(_VF) (0x00130800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_CQACK_MAX_INDEX 127
+#define I40E_VFPE_CQACK_PECQID_SHIFT 0
+#define I40E_VFPE_CQACK_PECQID_MASK I40E_MASK(0x1FFFF, I40E_VFPE_CQACK_PECQID_SHIFT)
+#define I40E_VFPE_CQARM(_VF) (0x00130400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_CQARM_MAX_INDEX 127
+#define I40E_VFPE_CQARM_PECQID_SHIFT 0
+#define I40E_VFPE_CQARM_PECQID_MASK I40E_MASK(0x1FFFF, I40E_VFPE_CQARM_PECQID_SHIFT)
+#define I40E_VFPE_CQPDB(_VF) (0x00000000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_CQPDB_MAX_INDEX 127
+#define I40E_VFPE_CQPDB_WQHEAD_SHIFT 0
+#define I40E_VFPE_CQPDB_WQHEAD_MASK I40E_MASK(0x7FF, I40E_VFPE_CQPDB_WQHEAD_SHIFT)
+#define I40E_VFPE_CQPERRCODES(_VF) (0x00001800 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_CQPERRCODES_MAX_INDEX 127
+#define I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT 0
+#define I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_MASK I40E_MASK(0xFFFF, I40E_VFPE_CQPERRCODES_CQP_MINOR_CODE_SHIFT)
+#define I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT 16
+#define I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_MASK I40E_MASK(0xFFFF, I40E_VFPE_CQPERRCODES_CQP_MAJOR_CODE_SHIFT)
+#define I40E_VFPE_CQPTAIL(_VF) (0x00000400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_CQPTAIL_MAX_INDEX 127
+#define I40E_VFPE_CQPTAIL_WQTAIL_SHIFT 0
+#define I40E_VFPE_CQPTAIL_WQTAIL_MASK I40E_MASK(0x7FF, I40E_VFPE_CQPTAIL_WQTAIL_SHIFT)
+#define I40E_VFPE_CQPTAIL_CQP_OP_ERR_SHIFT 31
+#define I40E_VFPE_CQPTAIL_CQP_OP_ERR_MASK I40E_MASK(0x1, I40E_VFPE_CQPTAIL_CQP_OP_ERR_SHIFT)
+#define I40E_VFPE_IPCONFIG0(_VF) (0x00001400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_IPCONFIG0_MAX_INDEX 127
+#define I40E_VFPE_IPCONFIG0_PEIPID_SHIFT 0
+#define I40E_VFPE_IPCONFIG0_PEIPID_MASK I40E_MASK(0xFFFF, I40E_VFPE_IPCONFIG0_PEIPID_SHIFT)
+#define I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT 16
+#define I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_MASK I40E_MASK(0x1, I40E_VFPE_IPCONFIG0_USEENTIREIDRANGE_SHIFT)
+#define I40E_VFPE_MRTEIDXMASK(_VF) (0x00003000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_MRTEIDXMASK_MAX_INDEX 127
+#define I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT 0
+#define I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_MASK I40E_MASK(0x1F, I40E_VFPE_MRTEIDXMASK_MRTEIDXMASKBITS_SHIFT)
+#define I40E_VFPE_RCVUNEXPECTEDERROR(_VF) (0x00003400 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_RCVUNEXPECTEDERROR_MAX_INDEX 127
+#define I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT 0
+#define I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_MASK I40E_MASK(0xFFFFFF, I40E_VFPE_RCVUNEXPECTEDERROR_TCP_RX_UNEXP_ERR_SHIFT)
+#define I40E_VFPE_TCPNOWTIMER(_VF) (0x00002C00 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_TCPNOWTIMER_MAX_INDEX 127
+#define I40E_VFPE_TCPNOWTIMER_TCP_NOW_SHIFT 0
+#define I40E_VFPE_TCPNOWTIMER_TCP_NOW_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_TCPNOWTIMER_TCP_NOW_SHIFT)
+#define I40E_VFPE_WQEALLOC(_VF) (0x00138000 + ((_VF) * 4)) /* _i=0...127 */ /* Reset: VFR */
+#define I40E_VFPE_WQEALLOC_MAX_INDEX 127
+#define I40E_VFPE_WQEALLOC_PEQPID_SHIFT 0
+#define I40E_VFPE_WQEALLOC_PEQPID_MASK I40E_MASK(0x3FFFF, I40E_VFPE_WQEALLOC_PEQPID_SHIFT)
+#define I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT 20
+#define I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_MASK I40E_MASK(0xFFF, I40E_VFPE_WQEALLOC_WQE_DESC_INDEX_SHIFT)
+#define I40E_GLPES_PFIP4RXDISCARD(_i) (0x00010600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXDISCARD_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_SHIFT 0
+#define I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXDISCARD_IP4RXDISCARD_SHIFT)
+#define I40E_GLPES_PFIP4RXFRAGSHI(_i) (0x00010804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXFRAGSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT 0
+#define I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT)
+#define I40E_GLPES_PFIP4RXFRAGSLO(_i) (0x00010800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXFRAGSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT 0
+#define I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT)
+#define I40E_GLPES_PFIP4RXMCOCTSHI(_i) (0x00010A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXMCOCTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT 0
+#define I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT)
+#define I40E_GLPES_PFIP4RXMCOCTSLO(_i) (0x00010A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXMCOCTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT 0
+#define I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT)
+#define I40E_GLPES_PFIP4RXMCPKTSHI(_i) (0x00010C04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXMCPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT 0
+#define I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT)
+#define I40E_GLPES_PFIP4RXMCPKTSLO(_i) (0x00010C00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXMCPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT 0
+#define I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT)
+#define I40E_GLPES_PFIP4RXOCTSHI(_i) (0x00010204 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXOCTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT 0
+#define I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT)
+#define I40E_GLPES_PFIP4RXOCTSLO(_i) (0x00010200 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXOCTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT 0
+#define I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT)
+#define I40E_GLPES_PFIP4RXPKTSHI(_i) (0x00010404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT 0
+#define I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT)
+#define I40E_GLPES_PFIP4RXPKTSLO(_i) (0x00010400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT 0
+#define I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT)
+#define I40E_GLPES_PFIP4RXTRUNC(_i) (0x00010700 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4RXTRUNC_MAX_INDEX 15
+#define I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_SHIFT 0
+#define I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4RXTRUNC_IP4RXTRUNC_SHIFT)
+#define I40E_GLPES_PFIP4TXFRAGSHI(_i) (0x00011E04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXFRAGSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT 0
+#define I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT)
+#define I40E_GLPES_PFIP4TXFRAGSLO(_i) (0x00011E00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXFRAGSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT 0
+#define I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT)
+#define I40E_GLPES_PFIP4TXMCOCTSHI(_i) (0x00012004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXMCOCTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT 0
+#define I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT)
+#define I40E_GLPES_PFIP4TXMCOCTSLO(_i) (0x00012000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXMCOCTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT 0
+#define I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT)
+#define I40E_GLPES_PFIP4TXMCPKTSHI(_i) (0x00012204 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXMCPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT 0
+#define I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT)
+#define I40E_GLPES_PFIP4TXMCPKTSLO(_i) (0x00012200 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXMCPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT 0
+#define I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT)
+#define I40E_GLPES_PFIP4TXNOROUTE(_i) (0x00012E00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXNOROUTE_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT 0
+#define I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT)
+#define I40E_GLPES_PFIP4TXOCTSHI(_i) (0x00011A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXOCTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT 0
+#define I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT)
+#define I40E_GLPES_PFIP4TXOCTSLO(_i) (0x00011A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXOCTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT 0
+#define I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT)
+#define I40E_GLPES_PFIP4TXPKTSHI(_i) (0x00011C04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT 0
+#define I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT)
+#define I40E_GLPES_PFIP4TXPKTSLO(_i) (0x00011C00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP4TXPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT 0
+#define I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT)
+#define I40E_GLPES_PFIP6RXDISCARD(_i) (0x00011200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXDISCARD_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_SHIFT 0
+#define I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXDISCARD_IP6RXDISCARD_SHIFT)
+#define I40E_GLPES_PFIP6RXFRAGSHI(_i) (0x00011404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXFRAGSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT 0
+#define I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT)
+#define I40E_GLPES_PFIP6RXFRAGSLO(_i) (0x00011400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXFRAGSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT 0
+#define I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT)
+#define I40E_GLPES_PFIP6RXMCOCTSHI(_i) (0x00011604 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXMCOCTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT 0
+#define I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT)
+#define I40E_GLPES_PFIP6RXMCOCTSLO(_i) (0x00011600 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXMCOCTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT 0
+#define I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT)
+#define I40E_GLPES_PFIP6RXMCPKTSHI(_i) (0x00011804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXMCPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT 0
+#define I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT)
+#define I40E_GLPES_PFIP6RXMCPKTSLO(_i) (0x00011800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXMCPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT 0
+#define I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT)
+#define I40E_GLPES_PFIP6RXOCTSHI(_i) (0x00010E04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXOCTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT 0
+#define I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT)
+#define I40E_GLPES_PFIP6RXOCTSLO(_i) (0x00010E00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXOCTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT 0
+#define I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT)
+#define I40E_GLPES_PFIP6RXPKTSHI(_i) (0x00011004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT 0
+#define I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT)
+#define I40E_GLPES_PFIP6RXPKTSLO(_i) (0x00011000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT 0
+#define I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT)
+#define I40E_GLPES_PFIP6RXTRUNC(_i) (0x00011300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6RXTRUNC_MAX_INDEX 15
+#define I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_SHIFT 0
+#define I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6RXTRUNC_IP6RXTRUNC_SHIFT)
+#define I40E_GLPES_PFIP6TXFRAGSHI(_i) (0x00012804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXFRAGSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT 0
+#define I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT)
+#define I40E_GLPES_PFIP6TXFRAGSLO(_i) (0x00012800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXFRAGSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT 0
+#define I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT)
+#define I40E_GLPES_PFIP6TXMCOCTSHI(_i) (0x00012A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXMCOCTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT 0
+#define I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT)
+#define I40E_GLPES_PFIP6TXMCOCTSLO(_i) (0x00012A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXMCOCTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT 0
+#define I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT)
+#define I40E_GLPES_PFIP6TXMCPKTSHI(_i) (0x00012C04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXMCPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT 0
+#define I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT)
+#define I40E_GLPES_PFIP6TXMCPKTSLO(_i) (0x00012C00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXMCPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT 0
+#define I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT)
+#define I40E_GLPES_PFIP6TXNOROUTE(_i) (0x00012F00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXNOROUTE_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT 0
+#define I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT)
+#define I40E_GLPES_PFIP6TXOCTSHI(_i) (0x00012404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXOCTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT 0
+#define I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT)
+#define I40E_GLPES_PFIP6TXOCTSLO(_i) (0x00012400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXOCTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT 0
+#define I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT)
+#define I40E_GLPES_PFIP6TXPKTSHI(_i) (0x00012604 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT 0
+#define I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT)
+#define I40E_GLPES_PFIP6TXPKTSLO(_i) (0x00012600 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFIP6TXPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT 0
+#define I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT)
+#define I40E_GLPES_PFRDMARXRDSHI(_i) (0x00013E04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMARXRDSHI_MAX_INDEX 15
+#define I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_SHIFT 0
+#define I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMARXRDSHI_RDMARXRDSHI_SHIFT)
+#define I40E_GLPES_PFRDMARXRDSLO(_i) (0x00013E00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMARXRDSLO_MAX_INDEX 15
+#define I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_SHIFT 0
+#define I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMARXRDSLO_RDMARXRDSLO_SHIFT)
+#define I40E_GLPES_PFRDMARXSNDSHI(_i) (0x00014004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMARXSNDSHI_MAX_INDEX 15
+#define I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT 0
+#define I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT)
+#define I40E_GLPES_PFRDMARXSNDSLO(_i) (0x00014000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMARXSNDSLO_MAX_INDEX 15
+#define I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT 0
+#define I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT)
+#define I40E_GLPES_PFRDMARXWRSHI(_i) (0x00013C04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMARXWRSHI_MAX_INDEX 15
+#define I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_SHIFT 0
+#define I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMARXWRSHI_RDMARXWRSHI_SHIFT)
+#define I40E_GLPES_PFRDMARXWRSLO(_i) (0x00013C00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMARXWRSLO_MAX_INDEX 15
+#define I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_SHIFT 0
+#define I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMARXWRSLO_RDMARXWRSLO_SHIFT)
+#define I40E_GLPES_PFRDMATXRDSHI(_i) (0x00014404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMATXRDSHI_MAX_INDEX 15
+#define I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_SHIFT 0
+#define I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMATXRDSHI_RDMARXRDSHI_SHIFT)
+#define I40E_GLPES_PFRDMATXRDSLO(_i) (0x00014400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMATXRDSLO_MAX_INDEX 15
+#define I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_SHIFT 0
+#define I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMATXRDSLO_RDMARXRDSLO_SHIFT)
+#define I40E_GLPES_PFRDMATXSNDSHI(_i) (0x00014604 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMATXSNDSHI_MAX_INDEX 15
+#define I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT 0
+#define I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT)
+#define I40E_GLPES_PFRDMATXSNDSLO(_i) (0x00014600 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMATXSNDSLO_MAX_INDEX 15
+#define I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT 0
+#define I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT)
+#define I40E_GLPES_PFRDMATXWRSHI(_i) (0x00014204 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMATXWRSHI_MAX_INDEX 15
+#define I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_SHIFT 0
+#define I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFRDMATXWRSHI_RDMARXWRSHI_SHIFT)
+#define I40E_GLPES_PFRDMATXWRSLO(_i) (0x00014200 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMATXWRSLO_MAX_INDEX 15
+#define I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_SHIFT 0
+#define I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMATXWRSLO_RDMARXWRSLO_SHIFT)
+#define I40E_GLPES_PFRDMAVBNDHI(_i) (0x00014804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMAVBNDHI_MAX_INDEX 15
+#define I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_SHIFT 0
+#define I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMAVBNDHI_RDMAVBNDHI_SHIFT)
+#define I40E_GLPES_PFRDMAVBNDLO(_i) (0x00014800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMAVBNDLO_MAX_INDEX 15
+#define I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_SHIFT 0
+#define I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMAVBNDLO_RDMAVBNDLO_SHIFT)
+#define I40E_GLPES_PFRDMAVINVHI(_i) (0x00014A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMAVINVHI_MAX_INDEX 15
+#define I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_SHIFT 0
+#define I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMAVINVHI_RDMAVINVHI_SHIFT)
+#define I40E_GLPES_PFRDMAVINVLO(_i) (0x00014A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRDMAVINVLO_MAX_INDEX 15
+#define I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_SHIFT 0
+#define I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFRDMAVINVLO_RDMAVINVLO_SHIFT)
+#define I40E_GLPES_PFRXVLANERR(_i) (0x00010000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFRXVLANERR_MAX_INDEX 15
+#define I40E_GLPES_PFRXVLANERR_RXVLANERR_SHIFT 0
+#define I40E_GLPES_PFRXVLANERR_RXVLANERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFRXVLANERR_RXVLANERR_SHIFT)
+#define I40E_GLPES_PFTCPRTXSEG(_i) (0x00013600 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFTCPRTXSEG_MAX_INDEX 15
+#define I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_SHIFT 0
+#define I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFTCPRTXSEG_TCPRTXSEG_SHIFT)
+#define I40E_GLPES_PFTCPRXOPTERR(_i) (0x00013200 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFTCPRXOPTERR_MAX_INDEX 15
+#define I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_SHIFT 0
+#define I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFTCPRXOPTERR_TCPRXOPTERR_SHIFT)
+#define I40E_GLPES_PFTCPRXPROTOERR(_i) (0x00013300 + ((_i) * 4)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFTCPRXPROTOERR_MAX_INDEX 15
+#define I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT 0
+#define I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_PFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT)
+#define I40E_GLPES_PFTCPRXSEGSHI(_i) (0x00013004 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFTCPRXSEGSHI_MAX_INDEX 15
+#define I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT 0
+#define I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT)
+#define I40E_GLPES_PFTCPRXSEGSLO(_i) (0x00013000 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFTCPRXSEGSLO_MAX_INDEX 15
+#define I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT 0
+#define I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT)
+#define I40E_GLPES_PFTCPTXSEGHI(_i) (0x00013404 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFTCPTXSEGHI_MAX_INDEX 15
+#define I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_SHIFT 0
+#define I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFTCPTXSEGHI_TCPTXSEGHI_SHIFT)
+#define I40E_GLPES_PFTCPTXSEGLO(_i) (0x00013400 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFTCPTXSEGLO_MAX_INDEX 15
+#define I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_SHIFT 0
+#define I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFTCPTXSEGLO_TCPTXSEGLO_SHIFT)
+#define I40E_GLPES_PFUDPRXPKTSHI(_i) (0x00013804 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFUDPRXPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT 0
+#define I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT)
+#define I40E_GLPES_PFUDPRXPKTSLO(_i) (0x00013800 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFUDPRXPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT 0
+#define I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT)
+#define I40E_GLPES_PFUDPTXPKTSHI(_i) (0x00013A04 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFUDPTXPKTSHI_MAX_INDEX 15
+#define I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT 0
+#define I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_PFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT)
+#define I40E_GLPES_PFUDPTXPKTSLO(_i) (0x00013A00 + ((_i) * 8)) /* _i=0...15 */ /* Reset: PE_CORER */
+#define I40E_GLPES_PFUDPTXPKTSLO_MAX_INDEX 15
+#define I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT 0
+#define I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_PFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT)
+#define I40E_GLPES_RDMARXMULTFPDUSHI 0x0001E014 /* Reset: PE_CORER */
+#define I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_SHIFT 0
+#define I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_RDMARXMULTFPDUSHI_RDMARXMULTFPDUSHI_SHIFT)
+#define I40E_GLPES_RDMARXMULTFPDUSLO 0x0001E010 /* Reset: PE_CORER */
+#define I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_SHIFT 0
+#define I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_RDMARXMULTFPDUSLO_RDMARXMULTFPDUSLO_SHIFT)
+#define I40E_GLPES_RDMARXOOODDPHI 0x0001E01C /* Reset: PE_CORER */
+#define I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_SHIFT 0
+#define I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_RDMARXOOODDPHI_RDMARXOOODDPHI_SHIFT)
+#define I40E_GLPES_RDMARXOOODDPLO 0x0001E018 /* Reset: PE_CORER */
+#define I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_SHIFT 0
+#define I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_RDMARXOOODDPLO_RDMARXOOODDPLO_SHIFT)
+#define I40E_GLPES_RDMARXOOONOMARK 0x0001E004 /* Reset: PE_CORER */
+#define I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_SHIFT 0
+#define I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_RDMARXOOONOMARK_RDMAOOONOMARK_SHIFT)
+#define I40E_GLPES_RDMARXUNALIGN 0x0001E000 /* Reset: PE_CORER */
+#define I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_SHIFT 0
+#define I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_RDMARXUNALIGN_RDMRXAUNALIGN_SHIFT)
+#define I40E_GLPES_TCPRXFOURHOLEHI 0x0001E044 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_SHIFT 0
+#define I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXFOURHOLEHI_TCPRXFOURHOLEHI_SHIFT)
+#define I40E_GLPES_TCPRXFOURHOLELO 0x0001E040 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_SHIFT 0
+#define I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXFOURHOLELO_TCPRXFOURHOLELO_SHIFT)
+#define I40E_GLPES_TCPRXONEHOLEHI 0x0001E02C /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_SHIFT 0
+#define I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXONEHOLEHI_TCPRXONEHOLEHI_SHIFT)
+#define I40E_GLPES_TCPRXONEHOLELO 0x0001E028 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_SHIFT 0
+#define I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXONEHOLELO_TCPRXONEHOLELO_SHIFT)
+#define I40E_GLPES_TCPRXPUREACKHI 0x0001E024 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_SHIFT 0
+#define I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXPUREACKHI_TCPRXPUREACKSHI_SHIFT)
+#define I40E_GLPES_TCPRXPUREACKSLO 0x0001E020 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_SHIFT 0
+#define I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXPUREACKSLO_TCPRXPUREACKLO_SHIFT)
+#define I40E_GLPES_TCPRXTHREEHOLEHI 0x0001E03C /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_SHIFT 0
+#define I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXTHREEHOLEHI_TCPRXTHREEHOLEHI_SHIFT)
+#define I40E_GLPES_TCPRXTHREEHOLELO 0x0001E038 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_SHIFT 0
+#define I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXTHREEHOLELO_TCPRXTHREEHOLELO_SHIFT)
+#define I40E_GLPES_TCPRXTWOHOLEHI 0x0001E034 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_SHIFT 0
+#define I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPRXTWOHOLEHI_TCPRXTWOHOLEHI_SHIFT)
+#define I40E_GLPES_TCPRXTWOHOLELO 0x0001E030 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_SHIFT 0
+#define I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPRXTWOHOLELO_TCPRXTWOHOLELO_SHIFT)
+#define I40E_GLPES_TCPTXRETRANSFASTHI 0x0001E04C /* Reset: PE_CORER */
+#define I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_SHIFT 0
+#define I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPTXRETRANSFASTHI_TCPTXRETRANSFASTHI_SHIFT)
+#define I40E_GLPES_TCPTXRETRANSFASTLO 0x0001E048 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_SHIFT 0
+#define I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPTXRETRANSFASTLO_TCPTXRETRANSFASTLO_SHIFT)
+#define I40E_GLPES_TCPTXTOUTSFASTHI 0x0001E054 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_SHIFT 0
+#define I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPTXTOUTSFASTHI_TCPTXTOUTSFASTHI_SHIFT)
+#define I40E_GLPES_TCPTXTOUTSFASTLO 0x0001E050 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_SHIFT 0
+#define I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPTXTOUTSFASTLO_TCPTXTOUTSFASTLO_SHIFT)
+#define I40E_GLPES_TCPTXTOUTSHI 0x0001E05C /* Reset: PE_CORER */
+#define I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_SHIFT 0
+#define I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_TCPTXTOUTSHI_TCPTXTOUTSHI_SHIFT)
+#define I40E_GLPES_TCPTXTOUTSLO 0x0001E058 /* Reset: PE_CORER */
+#define I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_SHIFT 0
+#define I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_TCPTXTOUTSLO_TCPTXTOUTSLO_SHIFT)
+#define I40E_GLPES_VFIP4RXDISCARD(_i) (0x00018600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXDISCARD_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_SHIFT 0
+#define I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXDISCARD_IP4RXDISCARD_SHIFT)
+#define I40E_GLPES_VFIP4RXFRAGSHI(_i) (0x00018804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXFRAGSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT 0
+#define I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXFRAGSHI_IP4RXFRAGSHI_SHIFT)
+#define I40E_GLPES_VFIP4RXFRAGSLO(_i) (0x00018800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXFRAGSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT 0
+#define I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXFRAGSLO_IP4RXFRAGSLO_SHIFT)
+#define I40E_GLPES_VFIP4RXMCOCTSHI(_i) (0x00018A04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXMCOCTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT 0
+#define I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXMCOCTSHI_IP4RXMCOCTSHI_SHIFT)
+#define I40E_GLPES_VFIP4RXMCOCTSLO(_i) (0x00018A00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXMCOCTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT 0
+#define I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXMCOCTSLO_IP4RXMCOCTSLO_SHIFT)
+#define I40E_GLPES_VFIP4RXMCPKTSHI(_i) (0x00018C04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXMCPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT 0
+#define I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXMCPKTSHI_IP4RXMCPKTSHI_SHIFT)
+#define I40E_GLPES_VFIP4RXMCPKTSLO(_i) (0x00018C00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXMCPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT 0
+#define I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXMCPKTSLO_IP4RXMCPKTSLO_SHIFT)
+#define I40E_GLPES_VFIP4RXOCTSHI(_i) (0x00018204 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXOCTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT 0
+#define I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXOCTSHI_IP4RXOCTSHI_SHIFT)
+#define I40E_GLPES_VFIP4RXOCTSLO(_i) (0x00018200 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXOCTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT 0
+#define I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXOCTSLO_IP4RXOCTSLO_SHIFT)
+#define I40E_GLPES_VFIP4RXPKTSHI(_i) (0x00018404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT 0
+#define I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4RXPKTSHI_IP4RXPKTSHI_SHIFT)
+#define I40E_GLPES_VFIP4RXPKTSLO(_i) (0x00018400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT 0
+#define I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXPKTSLO_IP4RXPKTSLO_SHIFT)
+#define I40E_GLPES_VFIP4RXTRUNC(_i) (0x00018700 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4RXTRUNC_MAX_INDEX 31
+#define I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_SHIFT 0
+#define I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4RXTRUNC_IP4RXTRUNC_SHIFT)
+#define I40E_GLPES_VFIP4TXFRAGSHI(_i) (0x00019E04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXFRAGSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT 0
+#define I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXFRAGSHI_IP4TXFRAGSHI_SHIFT)
+#define I40E_GLPES_VFIP4TXFRAGSLO(_i) (0x00019E00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXFRAGSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT 0
+#define I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXFRAGSLO_IP4TXFRAGSLO_SHIFT)
+#define I40E_GLPES_VFIP4TXMCOCTSHI(_i) (0x0001A004 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXMCOCTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT 0
+#define I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXMCOCTSHI_IP4TXMCOCTSHI_SHIFT)
+#define I40E_GLPES_VFIP4TXMCOCTSLO(_i) (0x0001A000 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXMCOCTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT 0
+#define I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXMCOCTSLO_IP4TXMCOCTSLO_SHIFT)
+#define I40E_GLPES_VFIP4TXMCPKTSHI(_i) (0x0001A204 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXMCPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT 0
+#define I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXMCPKTSHI_IP4TXMCPKTSHI_SHIFT)
+#define I40E_GLPES_VFIP4TXMCPKTSLO(_i) (0x0001A200 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXMCPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT 0
+#define I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXMCPKTSLO_IP4TXMCPKTSLO_SHIFT)
+#define I40E_GLPES_VFIP4TXNOROUTE(_i) (0x0001AE00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXNOROUTE_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT 0
+#define I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFIP4TXNOROUTE_IP4TXNOROUTE_SHIFT)
+#define I40E_GLPES_VFIP4TXOCTSHI(_i) (0x00019A04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXOCTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT 0
+#define I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXOCTSHI_IP4TXOCTSHI_SHIFT)
+#define I40E_GLPES_VFIP4TXOCTSLO(_i) (0x00019A00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXOCTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT 0
+#define I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXOCTSLO_IP4TXOCTSLO_SHIFT)
+#define I40E_GLPES_VFIP4TXPKTSHI(_i) (0x00019C04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT 0
+#define I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP4TXPKTSHI_IP4TXPKTSHI_SHIFT)
+#define I40E_GLPES_VFIP4TXPKTSLO(_i) (0x00019C00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP4TXPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT 0
+#define I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP4TXPKTSLO_IP4TXPKTSLO_SHIFT)
+#define I40E_GLPES_VFIP6RXDISCARD(_i) (0x00019200 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXDISCARD_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_SHIFT 0
+#define I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXDISCARD_IP6RXDISCARD_SHIFT)
+#define I40E_GLPES_VFIP6RXFRAGSHI(_i) (0x00019404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXFRAGSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT 0
+#define I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXFRAGSHI_IP6RXFRAGSHI_SHIFT)
+#define I40E_GLPES_VFIP6RXFRAGSLO(_i) (0x00019400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXFRAGSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT 0
+#define I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXFRAGSLO_IP6RXFRAGSLO_SHIFT)
+#define I40E_GLPES_VFIP6RXMCOCTSHI(_i) (0x00019604 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXMCOCTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT 0
+#define I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXMCOCTSHI_IP6RXMCOCTSHI_SHIFT)
+#define I40E_GLPES_VFIP6RXMCOCTSLO(_i) (0x00019600 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXMCOCTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT 0
+#define I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXMCOCTSLO_IP6RXMCOCTSLO_SHIFT)
+#define I40E_GLPES_VFIP6RXMCPKTSHI(_i) (0x00019804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXMCPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT 0
+#define I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXMCPKTSHI_IP6RXMCPKTSHI_SHIFT)
+#define I40E_GLPES_VFIP6RXMCPKTSLO(_i) (0x00019800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXMCPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT 0
+#define I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXMCPKTSLO_IP6RXMCPKTSLO_SHIFT)
+#define I40E_GLPES_VFIP6RXOCTSHI(_i) (0x00018E04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXOCTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT 0
+#define I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXOCTSHI_IP6RXOCTSHI_SHIFT)
+#define I40E_GLPES_VFIP6RXOCTSLO(_i) (0x00018E00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXOCTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT 0
+#define I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXOCTSLO_IP6RXOCTSLO_SHIFT)
+#define I40E_GLPES_VFIP6RXPKTSHI(_i) (0x00019004 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT 0
+#define I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6RXPKTSHI_IP6RXPKTSHI_SHIFT)
+#define I40E_GLPES_VFIP6RXPKTSLO(_i) (0x00019000 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT 0
+#define I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXPKTSLO_IP6RXPKTSLO_SHIFT)
+#define I40E_GLPES_VFIP6RXTRUNC(_i) (0x00019300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6RXTRUNC_MAX_INDEX 31
+#define I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_SHIFT 0
+#define I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6RXTRUNC_IP6RXTRUNC_SHIFT)
+#define I40E_GLPES_VFIP6TXFRAGSHI(_i) (0x0001A804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXFRAGSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT 0
+#define I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXFRAGSHI_IP6TXFRAGSHI_SHIFT)
+#define I40E_GLPES_VFIP6TXFRAGSLO(_i) (0x0001A800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXFRAGSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT 0
+#define I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXFRAGSLO_IP6TXFRAGSLO_SHIFT)
+#define I40E_GLPES_VFIP6TXMCOCTSHI(_i) (0x0001AA04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXMCOCTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT 0
+#define I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXMCOCTSHI_IP6TXMCOCTSHI_SHIFT)
+#define I40E_GLPES_VFIP6TXMCOCTSLO(_i) (0x0001AA00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXMCOCTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT 0
+#define I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXMCOCTSLO_IP6TXMCOCTSLO_SHIFT)
+#define I40E_GLPES_VFIP6TXMCPKTSHI(_i) (0x0001AC04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXMCPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT 0
+#define I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXMCPKTSHI_IP6TXMCPKTSHI_SHIFT)
+#define I40E_GLPES_VFIP6TXMCPKTSLO(_i) (0x0001AC00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXMCPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT 0
+#define I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXMCPKTSLO_IP6TXMCPKTSLO_SHIFT)
+#define I40E_GLPES_VFIP6TXNOROUTE(_i) (0x0001AF00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXNOROUTE_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT 0
+#define I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFIP6TXNOROUTE_IP6TXNOROUTE_SHIFT)
+#define I40E_GLPES_VFIP6TXOCTSHI(_i) (0x0001A404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXOCTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT 0
+#define I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXOCTSHI_IP6TXOCTSHI_SHIFT)
+#define I40E_GLPES_VFIP6TXOCTSLO(_i) (0x0001A400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXOCTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT 0
+#define I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXOCTSLO_IP6TXOCTSLO_SHIFT)
+#define I40E_GLPES_VFIP6TXPKTSHI(_i) (0x0001A604 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT 0
+#define I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFIP6TXPKTSHI_IP6TXPKTSHI_SHIFT)
+#define I40E_GLPES_VFIP6TXPKTSLO(_i) (0x0001A600 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFIP6TXPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT 0
+#define I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFIP6TXPKTSLO_IP6TXPKTSLO_SHIFT)
+#define I40E_GLPES_VFRDMARXRDSHI(_i) (0x0001BE04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMARXRDSHI_MAX_INDEX 31
+#define I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_SHIFT 0
+#define I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMARXRDSHI_RDMARXRDSHI_SHIFT)
+#define I40E_GLPES_VFRDMARXRDSLO(_i) (0x0001BE00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMARXRDSLO_MAX_INDEX 31
+#define I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_SHIFT 0
+#define I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMARXRDSLO_RDMARXRDSLO_SHIFT)
+#define I40E_GLPES_VFRDMARXSNDSHI(_i) (0x0001C004 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMARXSNDSHI_MAX_INDEX 31
+#define I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT 0
+#define I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMARXSNDSHI_RDMARXSNDSHI_SHIFT)
+#define I40E_GLPES_VFRDMARXSNDSLO(_i) (0x0001C000 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMARXSNDSLO_MAX_INDEX 31
+#define I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT 0
+#define I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMARXSNDSLO_RDMARXSNDSLO_SHIFT)
+#define I40E_GLPES_VFRDMARXWRSHI(_i) (0x0001BC04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMARXWRSHI_MAX_INDEX 31
+#define I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_SHIFT 0
+#define I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMARXWRSHI_RDMARXWRSHI_SHIFT)
+#define I40E_GLPES_VFRDMARXWRSLO(_i) (0x0001BC00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMARXWRSLO_MAX_INDEX 31
+#define I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_SHIFT 0
+#define I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMARXWRSLO_RDMARXWRSLO_SHIFT)
+#define I40E_GLPES_VFRDMATXRDSHI(_i) (0x0001C404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMATXRDSHI_MAX_INDEX 31
+#define I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_SHIFT 0
+#define I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMATXRDSHI_RDMARXRDSHI_SHIFT)
+#define I40E_GLPES_VFRDMATXRDSLO(_i) (0x0001C400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMATXRDSLO_MAX_INDEX 31
+#define I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_SHIFT 0
+#define I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMATXRDSLO_RDMARXRDSLO_SHIFT)
+#define I40E_GLPES_VFRDMATXSNDSHI(_i) (0x0001C604 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMATXSNDSHI_MAX_INDEX 31
+#define I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT 0
+#define I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMATXSNDSHI_RDMARXSNDSHI_SHIFT)
+#define I40E_GLPES_VFRDMATXSNDSLO(_i) (0x0001C600 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMATXSNDSLO_MAX_INDEX 31
+#define I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT 0
+#define I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMATXSNDSLO_RDMARXSNDSLO_SHIFT)
+#define I40E_GLPES_VFRDMATXWRSHI(_i) (0x0001C204 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMATXWRSHI_MAX_INDEX 31
+#define I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_SHIFT 0
+#define I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFRDMATXWRSHI_RDMARXWRSHI_SHIFT)
+#define I40E_GLPES_VFRDMATXWRSLO(_i) (0x0001C200 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMATXWRSLO_MAX_INDEX 31
+#define I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_SHIFT 0
+#define I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMATXWRSLO_RDMARXWRSLO_SHIFT)
+#define I40E_GLPES_VFRDMAVBNDHI(_i) (0x0001C804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMAVBNDHI_MAX_INDEX 31
+#define I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_SHIFT 0
+#define I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMAVBNDHI_RDMAVBNDHI_SHIFT)
+#define I40E_GLPES_VFRDMAVBNDLO(_i) (0x0001C800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMAVBNDLO_MAX_INDEX 31
+#define I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_SHIFT 0
+#define I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMAVBNDLO_RDMAVBNDLO_SHIFT)
+#define I40E_GLPES_VFRDMAVINVHI(_i) (0x0001CA04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMAVINVHI_MAX_INDEX 31
+#define I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_SHIFT 0
+#define I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMAVINVHI_RDMAVINVHI_SHIFT)
+#define I40E_GLPES_VFRDMAVINVLO(_i) (0x0001CA00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRDMAVINVLO_MAX_INDEX 31
+#define I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_SHIFT 0
+#define I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFRDMAVINVLO_RDMAVINVLO_SHIFT)
+#define I40E_GLPES_VFRXVLANERR(_i) (0x00018000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFRXVLANERR_MAX_INDEX 31
+#define I40E_GLPES_VFRXVLANERR_RXVLANERR_SHIFT 0
+#define I40E_GLPES_VFRXVLANERR_RXVLANERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFRXVLANERR_RXVLANERR_SHIFT)
+#define I40E_GLPES_VFTCPRTXSEG(_i) (0x0001B600 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFTCPRTXSEG_MAX_INDEX 31
+#define I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_SHIFT 0
+#define I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFTCPRTXSEG_TCPRTXSEG_SHIFT)
+#define I40E_GLPES_VFTCPRXOPTERR(_i) (0x0001B200 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFTCPRXOPTERR_MAX_INDEX 31
+#define I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_SHIFT 0
+#define I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFTCPRXOPTERR_TCPRXOPTERR_SHIFT)
+#define I40E_GLPES_VFTCPRXPROTOERR(_i) (0x0001B300 + ((_i) * 4)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFTCPRXPROTOERR_MAX_INDEX 31
+#define I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT 0
+#define I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_MASK I40E_MASK(0xFFFFFF, I40E_GLPES_VFTCPRXPROTOERR_TCPRXPROTOERR_SHIFT)
+#define I40E_GLPES_VFTCPRXSEGSHI(_i) (0x0001B004 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFTCPRXSEGSHI_MAX_INDEX 31
+#define I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT 0
+#define I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFTCPRXSEGSHI_TCPRXSEGSHI_SHIFT)
+#define I40E_GLPES_VFTCPRXSEGSLO(_i) (0x0001B000 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFTCPRXSEGSLO_MAX_INDEX 31
+#define I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT 0
+#define I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFTCPRXSEGSLO_TCPRXSEGSLO_SHIFT)
+#define I40E_GLPES_VFTCPTXSEGHI(_i) (0x0001B404 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFTCPTXSEGHI_MAX_INDEX 31
+#define I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_SHIFT 0
+#define I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFTCPTXSEGHI_TCPTXSEGHI_SHIFT)
+#define I40E_GLPES_VFTCPTXSEGLO(_i) (0x0001B400 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFTCPTXSEGLO_MAX_INDEX 31
+#define I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_SHIFT 0
+#define I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFTCPTXSEGLO_TCPTXSEGLO_SHIFT)
+#define I40E_GLPES_VFUDPRXPKTSHI(_i) (0x0001B804 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFUDPRXPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT 0
+#define I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFUDPRXPKTSHI_UDPRXPKTSHI_SHIFT)
+#define I40E_GLPES_VFUDPRXPKTSLO(_i) (0x0001B800 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFUDPRXPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT 0
+#define I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFUDPRXPKTSLO_UDPRXPKTSLO_SHIFT)
+#define I40E_GLPES_VFUDPTXPKTSHI(_i) (0x0001BA04 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFUDPTXPKTSHI_MAX_INDEX 31
+#define I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT 0
+#define I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_MASK I40E_MASK(0xFFFF, I40E_GLPES_VFUDPTXPKTSHI_UDPTXPKTSHI_SHIFT)
+#define I40E_GLPES_VFUDPTXPKTSLO(_i) (0x0001BA00 + ((_i) * 8)) /* _i=0...31 */ /* Reset: PE_CORER */
+#define I40E_GLPES_VFUDPTXPKTSLO_MAX_INDEX 31
+#define I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT 0
+#define I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_MASK I40E_MASK(0xFFFFFFFF, I40E_GLPES_VFUDPTXPKTSLO_UDPTXPKTSLO_SHIFT)
+#define I40E_GLGEN_PME_TO 0x000B81BC /* Reset: POR */
+#define I40E_GLGEN_PME_TO_PME_TO_FOR_PE_SHIFT 0
+#define I40E_GLGEN_PME_TO_PME_TO_FOR_PE_MASK I40E_MASK(0x1, I40E_GLGEN_PME_TO_PME_TO_FOR_PE_SHIFT)
+#define I40E_GLQF_APBVT(_i) (0x00260000 + ((_i) * 4)) /* _i=0...2047 */ /* Reset: CORER */
+#define I40E_GLQF_APBVT_MAX_INDEX 2047
+#define I40E_GLQF_APBVT_APBVT_SHIFT 0
+#define I40E_GLQF_APBVT_APBVT_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_APBVT_APBVT_SHIFT)
+#define I40E_GLQF_FD_PCTYPES(_i) (0x00268000 + ((_i) * 4)) /* _i=0...63 */ /* Reset: POR */
+#define I40E_GLQF_FD_PCTYPES_MAX_INDEX 63
+#define I40E_GLQF_FD_PCTYPES_FD_PCTYPE_SHIFT 0
+#define I40E_GLQF_FD_PCTYPES_FD_PCTYPE_MASK I40E_MASK(0x3F, I40E_GLQF_FD_PCTYPES_FD_PCTYPE_SHIFT)
+#define I40E_GLQF_FDEVICTENA(_i) (0x00270384 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
+#define I40E_GLQF_FDEVICTENA_MAX_INDEX 1
+#define I40E_GLQF_FDEVICTENA_GLQF_FDEVICTENA_SHIFT 0
+#define I40E_GLQF_FDEVICTENA_GLQF_FDEVICTENA_MASK I40E_MASK(0xFFFFFFFF, I40E_GLQF_FDEVICTENA_GLQF_FDEVICTENA_SHIFT)
+#define I40E_GLQF_FDEVICTFLAG 0x00270280 /* Reset: CORER */
+#define I40E_GLQF_FDEVICTFLAG_TX_FLAGS_SHIFT 0
+#define I40E_GLQF_FDEVICTFLAG_TX_FLAGS_MASK I40E_MASK(0xFF, I40E_GLQF_FDEVICTFLAG_TX_FLAGS_SHIFT)
+#define I40E_GLQF_FDEVICTFLAG_RX_FLAGS_SHIFT 8
+#define I40E_GLQF_FDEVICTFLAG_RX_FLAGS_MASK I40E_MASK(0xFF, I40E_GLQF_FDEVICTFLAG_RX_FLAGS_SHIFT)
+#define I40E_PFQF_CTL_2 0x00270300 /* Reset: CORER */
+#define I40E_PFQF_CTL_2_PEHSIZE_SHIFT 0
+#define I40E_PFQF_CTL_2_PEHSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_2_PEHSIZE_SHIFT)
+#define I40E_PFQF_CTL_2_PEDSIZE_SHIFT 5
+#define I40E_PFQF_CTL_2_PEDSIZE_MASK I40E_MASK(0x1F, I40E_PFQF_CTL_2_PEDSIZE_SHIFT)
+/* Redefined for X722 family */
+#define I40E_X722_PFQF_HLUT(_i) (0x00240000 + ((_i) * 128)) /* _i=0...127 */ /* Reset: CORER */
+#define I40E_X722_PFQF_HLUT_MAX_INDEX 127
+#define I40E_X722_PFQF_HLUT_LUT0_SHIFT 0
+#define I40E_X722_PFQF_HLUT_LUT0_MASK I40E_MASK(0x7F, I40E_X722_PFQF_HLUT_LUT0_SHIFT)
+#define I40E_X722_PFQF_HLUT_LUT1_SHIFT 8
+#define I40E_X722_PFQF_HLUT_LUT1_MASK I40E_MASK(0x7F, I40E_X722_PFQF_HLUT_LUT1_SHIFT)
+#define I40E_X722_PFQF_HLUT_LUT2_SHIFT 16
+#define I40E_X722_PFQF_HLUT_LUT2_MASK I40E_MASK(0x7F, I40E_X722_PFQF_HLUT_LUT2_SHIFT)
+#define I40E_X722_PFQF_HLUT_LUT3_SHIFT 24
+#define I40E_X722_PFQF_HLUT_LUT3_MASK I40E_MASK(0x7F, I40E_X722_PFQF_HLUT_LUT3_SHIFT)
+#define I40E_PFQF_HREGION(_i) (0x00245400 + ((_i) * 128)) /* _i=0...7 */ /* Reset: CORER */
+#define I40E_PFQF_HREGION_MAX_INDEX 7
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT 0
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_0_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
+#define I40E_PFQF_HREGION_REGION_0_SHIFT 1
+#define I40E_PFQF_HREGION_REGION_0_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_0_SHIFT)
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT 4
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_1_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
+#define I40E_PFQF_HREGION_REGION_1_SHIFT 5
+#define I40E_PFQF_HREGION_REGION_1_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_1_SHIFT)
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT 8
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_2_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
+#define I40E_PFQF_HREGION_REGION_2_SHIFT 9
+#define I40E_PFQF_HREGION_REGION_2_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_2_SHIFT)
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT 12
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_3_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
+#define I40E_PFQF_HREGION_REGION_3_SHIFT 13
+#define I40E_PFQF_HREGION_REGION_3_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_3_SHIFT)
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT 16
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_4_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
+#define I40E_PFQF_HREGION_REGION_4_SHIFT 17
+#define I40E_PFQF_HREGION_REGION_4_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_4_SHIFT)
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT 20
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_5_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
+#define I40E_PFQF_HREGION_REGION_5_SHIFT 21
+#define I40E_PFQF_HREGION_REGION_5_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_5_SHIFT)
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT 24
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_6_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
+#define I40E_PFQF_HREGION_REGION_6_SHIFT 25
+#define I40E_PFQF_HREGION_REGION_6_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_6_SHIFT)
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT 28
+#define I40E_PFQF_HREGION_OVERRIDE_ENA_7_MASK I40E_MASK(0x1, I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
+#define I40E_PFQF_HREGION_REGION_7_SHIFT 29
+#define I40E_PFQF_HREGION_REGION_7_MASK I40E_MASK(0x7, I40E_PFQF_HREGION_REGION_7_SHIFT)
+#define I40E_VSIQF_CTL_RSS_LUT_TYPE_SHIFT 8
+#define I40E_VSIQF_CTL_RSS_LUT_TYPE_MASK I40E_MASK(0x1, I40E_VSIQF_CTL_RSS_LUT_TYPE_SHIFT)
+#define I40E_VSIQF_HKEY(_i, _VSI) (0x002A0000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...12, _VSI=0...383 */ /* Reset: CORER */
+#define I40E_VSIQF_HKEY_MAX_INDEX 12
+#define I40E_VSIQF_HKEY_KEY_0_SHIFT 0
+#define I40E_VSIQF_HKEY_KEY_0_MASK I40E_MASK(0xFF, I40E_VSIQF_HKEY_KEY_0_SHIFT)
+#define I40E_VSIQF_HKEY_KEY_1_SHIFT 8
+#define I40E_VSIQF_HKEY_KEY_1_MASK I40E_MASK(0xFF, I40E_VSIQF_HKEY_KEY_1_SHIFT)
+#define I40E_VSIQF_HKEY_KEY_2_SHIFT 16
+#define I40E_VSIQF_HKEY_KEY_2_MASK I40E_MASK(0xFF, I40E_VSIQF_HKEY_KEY_2_SHIFT)
+#define I40E_VSIQF_HKEY_KEY_3_SHIFT 24
+#define I40E_VSIQF_HKEY_KEY_3_MASK I40E_MASK(0xFF, I40E_VSIQF_HKEY_KEY_3_SHIFT)
+#define I40E_VSIQF_HLUT(_i, _VSI) (0x00220000 + ((_i) * 2048 + (_VSI) * 4)) /* _i=0...15, _VSI=0...383 */ /* Reset: CORER */
+#define I40E_VSIQF_HLUT_MAX_INDEX 15
+#define I40E_VSIQF_HLUT_LUT0_SHIFT 0
+#define I40E_VSIQF_HLUT_LUT0_MASK I40E_MASK(0xF, I40E_VSIQF_HLUT_LUT0_SHIFT)
+#define I40E_VSIQF_HLUT_LUT1_SHIFT 8
+#define I40E_VSIQF_HLUT_LUT1_MASK I40E_MASK(0xF, I40E_VSIQF_HLUT_LUT1_SHIFT)
+#define I40E_VSIQF_HLUT_LUT2_SHIFT 16
+#define I40E_VSIQF_HLUT_LUT2_MASK I40E_MASK(0xF, I40E_VSIQF_HLUT_LUT2_SHIFT)
+#define I40E_VSIQF_HLUT_LUT3_SHIFT 24
+#define I40E_VSIQF_HLUT_LUT3_MASK I40E_MASK(0xF, I40E_VSIQF_HLUT_LUT3_SHIFT)
+#define I40E_GLGEN_STAT_CLEAR 0x00390004 /* Reset: CORER */
+#define I40E_GLGEN_STAT_CLEAR_GLGEN_STAT_CLEAR_SHIFT 0
+#define I40E_GLGEN_STAT_CLEAR_GLGEN_STAT_CLEAR_MASK I40E_MASK(0x1, I40E_GLGEN_STAT_CLEAR_GLGEN_STAT_CLEAR_SHIFT)
+#define I40E_GLGEN_STAT_HALT 0x00390000 /* Reset: CORER */
+#define I40E_GLGEN_STAT_HALT_HALT_CELLS_SHIFT 0
+#define I40E_GLGEN_STAT_HALT_HALT_CELLS_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_STAT_HALT_HALT_CELLS_SHIFT)
+#define I40E_VFINT_DYN_CTL01_WB_ON_ITR_SHIFT 30
+#define I40E_VFINT_DYN_CTL01_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_WB_ON_ITR_SHIFT)
+#define I40E_VFINT_DYN_CTLN1_WB_ON_ITR_SHIFT 30
+#define I40E_VFINT_DYN_CTLN1_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTLN1_WB_ON_ITR_SHIFT)
+#define I40E_VFPE_AEQALLOC1 0x0000A400 /* Reset: VFR */
+#define I40E_VFPE_AEQALLOC1_AECOUNT_SHIFT 0
+#define I40E_VFPE_AEQALLOC1_AECOUNT_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_AEQALLOC1_AECOUNT_SHIFT)
+#define I40E_VFPE_CCQPHIGH1 0x00009800 /* Reset: VFR */
+#define I40E_VFPE_CCQPHIGH1_PECCQPHIGH_SHIFT 0
+#define I40E_VFPE_CCQPHIGH1_PECCQPHIGH_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_CCQPHIGH1_PECCQPHIGH_SHIFT)
+#define I40E_VFPE_CCQPLOW1 0x0000AC00 /* Reset: VFR */
+#define I40E_VFPE_CCQPLOW1_PECCQPLOW_SHIFT 0
+#define I40E_VFPE_CCQPLOW1_PECCQPLOW_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_CCQPLOW1_PECCQPLOW_SHIFT)
+#define I40E_VFPE_CCQPSTATUS1 0x0000B800 /* Reset: VFR */
+#define I40E_VFPE_CCQPSTATUS1_CCQP_DONE_SHIFT 0
+#define I40E_VFPE_CCQPSTATUS1_CCQP_DONE_MASK I40E_MASK(0x1, I40E_VFPE_CCQPSTATUS1_CCQP_DONE_SHIFT)
+#define I40E_VFPE_CCQPSTATUS1_HMC_PROFILE_SHIFT 4
+#define I40E_VFPE_CCQPSTATUS1_HMC_PROFILE_MASK I40E_MASK(0x7, I40E_VFPE_CCQPSTATUS1_HMC_PROFILE_SHIFT)
+#define I40E_VFPE_CCQPSTATUS1_RDMA_EN_VFS_SHIFT 16
+#define I40E_VFPE_CCQPSTATUS1_RDMA_EN_VFS_MASK I40E_MASK(0x3F, I40E_VFPE_CCQPSTATUS1_RDMA_EN_VFS_SHIFT)
+#define I40E_VFPE_CCQPSTATUS1_CCQP_ERR_SHIFT 31
+#define I40E_VFPE_CCQPSTATUS1_CCQP_ERR_MASK I40E_MASK(0x1, I40E_VFPE_CCQPSTATUS1_CCQP_ERR_SHIFT)
+#define I40E_VFPE_CQACK1 0x0000B000 /* Reset: VFR */
+#define I40E_VFPE_CQACK1_PECQID_SHIFT 0
+#define I40E_VFPE_CQACK1_PECQID_MASK I40E_MASK(0x1FFFF, I40E_VFPE_CQACK1_PECQID_SHIFT)
+#define I40E_VFPE_CQARM1 0x0000B400 /* Reset: VFR */
+#define I40E_VFPE_CQARM1_PECQID_SHIFT 0
+#define I40E_VFPE_CQARM1_PECQID_MASK I40E_MASK(0x1FFFF, I40E_VFPE_CQARM1_PECQID_SHIFT)
+#define I40E_VFPE_CQPDB1 0x0000BC00 /* Reset: VFR */
+#define I40E_VFPE_CQPDB1_WQHEAD_SHIFT 0
+#define I40E_VFPE_CQPDB1_WQHEAD_MASK I40E_MASK(0x7FF, I40E_VFPE_CQPDB1_WQHEAD_SHIFT)
+#define I40E_VFPE_CQPERRCODES1 0x00009C00 /* Reset: VFR */
+#define I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT 0
+#define I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_MASK I40E_MASK(0xFFFF, I40E_VFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT)
+#define I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT 16
+#define I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_MASK I40E_MASK(0xFFFF, I40E_VFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT)
+#define I40E_VFPE_CQPTAIL1 0x0000A000 /* Reset: VFR */
+#define I40E_VFPE_CQPTAIL1_WQTAIL_SHIFT 0
+#define I40E_VFPE_CQPTAIL1_WQTAIL_MASK I40E_MASK(0x7FF, I40E_VFPE_CQPTAIL1_WQTAIL_SHIFT)
+#define I40E_VFPE_CQPTAIL1_CQP_OP_ERR_SHIFT 31
+#define I40E_VFPE_CQPTAIL1_CQP_OP_ERR_MASK I40E_MASK(0x1, I40E_VFPE_CQPTAIL1_CQP_OP_ERR_SHIFT)
+#define I40E_VFPE_IPCONFIG01 0x00008C00 /* Reset: VFR */
+#define I40E_VFPE_IPCONFIG01_PEIPID_SHIFT 0
+#define I40E_VFPE_IPCONFIG01_PEIPID_MASK I40E_MASK(0xFFFF, I40E_VFPE_IPCONFIG01_PEIPID_SHIFT)
+#define I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT 16
+#define I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_MASK I40E_MASK(0x1, I40E_VFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT)
+#define I40E_VFPE_MRTEIDXMASK1 0x00009000 /* Reset: VFR */
+#define I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT 0
+#define I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_MASK I40E_MASK(0x1F, I40E_VFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT)
+#define I40E_VFPE_RCVUNEXPECTEDERROR1 0x00009400 /* Reset: VFR */
+#define I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT 0
+#define I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_MASK I40E_MASK(0xFFFFFF, I40E_VFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT)
+#define I40E_VFPE_TCPNOWTIMER1 0x0000A800 /* Reset: VFR */
+#define I40E_VFPE_TCPNOWTIMER1_TCP_NOW_SHIFT 0
+#define I40E_VFPE_TCPNOWTIMER1_TCP_NOW_MASK I40E_MASK(0xFFFFFFFF, I40E_VFPE_TCPNOWTIMER1_TCP_NOW_SHIFT)
+#define I40E_VFPE_WQEALLOC1 0x0000C000 /* Reset: VFR */
+#define I40E_VFPE_WQEALLOC1_PEQPID_SHIFT 0
+#define I40E_VFPE_WQEALLOC1_PEQPID_MASK I40E_MASK(0x3FFFF, I40E_VFPE_WQEALLOC1_PEQPID_SHIFT)
+#define I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT 20
+#define I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_MASK I40E_MASK(0xFFF, I40E_VFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT)
+
+#endif /* X722_SUPPORT */
#endif /* _I40E_REGISTER_H_ */
diff --git a/sys/dev/ixl/i40e_type.h b/sys/dev/ixl/i40e_type.h
index 1de747dfc9a4..01762e7075c1 100644
--- a/sys/dev/ixl/i40e_type.h
+++ b/sys/dev/ixl/i40e_type.h
@@ -41,29 +41,12 @@
#include "i40e_adminq.h"
#include "i40e_hmc.h"
#include "i40e_lan_hmc.h"
+#include "i40e_devids.h"
#define UNREFERENCED_XPARAMETER
-/* Vendor ID */
-#define I40E_INTEL_VENDOR_ID 0x8086
-
-/* Device IDs */
-#define I40E_DEV_ID_SFP_XL710 0x1572
-#define I40E_DEV_ID_QEMU 0x1574
-#define I40E_DEV_ID_KX_A 0x157F
-#define I40E_DEV_ID_KX_B 0x1580
-#define I40E_DEV_ID_KX_C 0x1581
-#define I40E_DEV_ID_QSFP_A 0x1583
-#define I40E_DEV_ID_QSFP_B 0x1584
-#define I40E_DEV_ID_QSFP_C 0x1585
-#define I40E_DEV_ID_10G_BASE_T 0x1586
-#define I40E_DEV_ID_20G_KR2 0x1587
-#define I40E_DEV_ID_VF 0x154C
-#define I40E_DEV_ID_VF_HV 0x1571
-
-#define i40e_is_40G_device(d) ((d) == I40E_DEV_ID_QSFP_A || \
- (d) == I40E_DEV_ID_QSFP_B || \
- (d) == I40E_DEV_ID_QSFP_C)
+#define BIT(a) (1UL << (a))
+#define BIT_ULL(a) (1ULL << (a))
#ifndef I40E_MASK
/* I40E_MASK is a macro used on 32 bit registers */
@@ -191,6 +174,10 @@ enum i40e_mac_type {
I40E_MAC_X710,
I40E_MAC_XL710,
I40E_MAC_VF,
+#ifdef X722_SUPPORT
+ I40E_MAC_X722,
+ I40E_MAC_X722_VF,
+#endif
I40E_MAC_GENERIC,
};
@@ -222,14 +209,14 @@ enum i40e_set_fc_aq_failures {
};
enum i40e_vsi_type {
- I40E_VSI_MAIN = 0,
- I40E_VSI_VMDQ1,
- I40E_VSI_VMDQ2,
- I40E_VSI_CTRL,
- I40E_VSI_FCOE,
- I40E_VSI_MIRROR,
- I40E_VSI_SRIOV,
- I40E_VSI_FDIR,
+ I40E_VSI_MAIN = 0,
+ I40E_VSI_VMDQ1 = 1,
+ I40E_VSI_VMDQ2 = 2,
+ I40E_VSI_CTRL = 3,
+ I40E_VSI_FCOE = 4,
+ I40E_VSI_MIRROR = 5,
+ I40E_VSI_SRIOV = 6,
+ I40E_VSI_FDIR = 7,
I40E_VSI_TYPE_UNKNOWN
};
@@ -253,16 +240,64 @@ struct i40e_link_status {
bool crc_enable;
u8 pacing;
u8 requested_speeds;
+ u8 module_type[3];
+ /* 1st byte: module identifier */
+#define I40E_MODULE_TYPE_SFP 0x03
+#define I40E_MODULE_TYPE_QSFP 0x0D
+ /* 2nd byte: ethernet compliance codes for 10/40G */
+#define I40E_MODULE_TYPE_40G_ACTIVE 0x01
+#define I40E_MODULE_TYPE_40G_LR4 0x02
+#define I40E_MODULE_TYPE_40G_SR4 0x04
+#define I40E_MODULE_TYPE_40G_CR4 0x08
+#define I40E_MODULE_TYPE_10G_BASE_SR 0x10
+#define I40E_MODULE_TYPE_10G_BASE_LR 0x20
+#define I40E_MODULE_TYPE_10G_BASE_LRM 0x40
+#define I40E_MODULE_TYPE_10G_BASE_ER 0x80
+ /* 3rd byte: ethernet compliance codes for 1G */
+#define I40E_MODULE_TYPE_1000BASE_SX 0x01
+#define I40E_MODULE_TYPE_1000BASE_LX 0x02
+#define I40E_MODULE_TYPE_1000BASE_CX 0x04
+#define I40E_MODULE_TYPE_1000BASE_T 0x08
+};
+
+enum i40e_aq_capabilities_phy_type {
+ I40E_CAP_PHY_TYPE_SGMII = BIT(I40E_PHY_TYPE_SGMII),
+ I40E_CAP_PHY_TYPE_1000BASE_KX = BIT(I40E_PHY_TYPE_1000BASE_KX),
+ I40E_CAP_PHY_TYPE_10GBASE_KX4 = BIT(I40E_PHY_TYPE_10GBASE_KX4),
+ I40E_CAP_PHY_TYPE_10GBASE_KR = BIT(I40E_PHY_TYPE_10GBASE_KR),
+ I40E_CAP_PHY_TYPE_40GBASE_KR4 = BIT(I40E_PHY_TYPE_40GBASE_KR4),
+ I40E_CAP_PHY_TYPE_XAUI = BIT(I40E_PHY_TYPE_XAUI),
+ I40E_CAP_PHY_TYPE_XFI = BIT(I40E_PHY_TYPE_XFI),
+ I40E_CAP_PHY_TYPE_SFI = BIT(I40E_PHY_TYPE_SFI),
+ I40E_CAP_PHY_TYPE_XLAUI = BIT(I40E_PHY_TYPE_XLAUI),
+ I40E_CAP_PHY_TYPE_XLPPI = BIT(I40E_PHY_TYPE_XLPPI),
+ I40E_CAP_PHY_TYPE_40GBASE_CR4_CU = BIT(I40E_PHY_TYPE_40GBASE_CR4_CU),
+ I40E_CAP_PHY_TYPE_10GBASE_CR1_CU = BIT(I40E_PHY_TYPE_10GBASE_CR1_CU),
+ I40E_CAP_PHY_TYPE_10GBASE_AOC = BIT(I40E_PHY_TYPE_10GBASE_AOC),
+ I40E_CAP_PHY_TYPE_40GBASE_AOC = BIT(I40E_PHY_TYPE_40GBASE_AOC),
+ I40E_CAP_PHY_TYPE_100BASE_TX = BIT(I40E_PHY_TYPE_100BASE_TX),
+ I40E_CAP_PHY_TYPE_1000BASE_T = BIT(I40E_PHY_TYPE_1000BASE_T),
+ I40E_CAP_PHY_TYPE_10GBASE_T = BIT(I40E_PHY_TYPE_10GBASE_T),
+ I40E_CAP_PHY_TYPE_10GBASE_SR = BIT(I40E_PHY_TYPE_10GBASE_SR),
+ I40E_CAP_PHY_TYPE_10GBASE_LR = BIT(I40E_PHY_TYPE_10GBASE_LR),
+ I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU = BIT(I40E_PHY_TYPE_10GBASE_SFPP_CU),
+ I40E_CAP_PHY_TYPE_10GBASE_CR1 = BIT(I40E_PHY_TYPE_10GBASE_CR1),
+ I40E_CAP_PHY_TYPE_40GBASE_CR4 = BIT(I40E_PHY_TYPE_40GBASE_CR4),
+ I40E_CAP_PHY_TYPE_40GBASE_SR4 = BIT(I40E_PHY_TYPE_40GBASE_SR4),
+ I40E_CAP_PHY_TYPE_40GBASE_LR4 = BIT(I40E_PHY_TYPE_40GBASE_LR4),
+ I40E_CAP_PHY_TYPE_1000BASE_SX = BIT(I40E_PHY_TYPE_1000BASE_SX),
+ I40E_CAP_PHY_TYPE_1000BASE_LX = BIT(I40E_PHY_TYPE_1000BASE_LX),
+ I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL = BIT(I40E_PHY_TYPE_1000BASE_T_OPTICAL),
+ I40E_CAP_PHY_TYPE_20GBASE_KR2 = BIT(I40E_PHY_TYPE_20GBASE_KR2)
};
struct i40e_phy_info {
struct i40e_link_status link_info;
struct i40e_link_status link_info_old;
- u32 autoneg_advertised;
- u32 phy_id;
- u32 module_type;
bool get_link_info;
enum i40e_media_type media_type;
+ /* all the phy types the NVM is capable of */
+ enum i40e_aq_capabilities_phy_type phy_types;
};
#define I40E_HW_CAP_MAX_GPIO 30
@@ -287,7 +322,17 @@ struct i40e_hw_capabilities {
bool dcb;
bool fcoe;
bool iscsi; /* Indicates iSCSI enabled */
- bool mfp_mode_1;
+ bool flex10_enable;
+ bool flex10_capable;
+ u32 flex10_mode;
+#define I40E_FLEX10_MODE_UNKNOWN 0x0
+#define I40E_FLEX10_MODE_DCC 0x1
+#define I40E_FLEX10_MODE_DCI 0x2
+
+ u32 flex10_status;
+#define I40E_FLEX10_STATUS_DCC_ERROR 0x1
+#define I40E_FLEX10_STATUS_VC_MODE 0x2
+
bool mgmt_cem;
bool ieee_1588;
bool iwarp;
@@ -316,6 +361,7 @@ struct i40e_hw_capabilities {
u8 rx_buf_chain_len;
u32 enabled_tcmap;
u32 maxtc;
+ u64 wr_csr_prot;
};
struct i40e_mac_info {
@@ -343,6 +389,7 @@ struct i40e_nvm_info {
bool blank_nvm_mode; /* is NVM empty (no FW present)*/
u16 version; /* NVM package version */
u32 eetrack; /* NVM data version */
+ u32 oem_ver; /* OEM version info */
};
/* definitions used in NVM update support */
@@ -361,12 +408,17 @@ enum i40e_nvmupd_cmd {
I40E_NVMUPD_CSUM_CON,
I40E_NVMUPD_CSUM_SA,
I40E_NVMUPD_CSUM_LCB,
+ I40E_NVMUPD_STATUS,
+ I40E_NVMUPD_EXEC_AQ,
+ I40E_NVMUPD_GET_AQ_RESULT,
};
enum i40e_nvmupd_state {
I40E_NVMUPD_STATE_INIT,
I40E_NVMUPD_STATE_READING,
- I40E_NVMUPD_STATE_WRITING
+ I40E_NVMUPD_STATE_WRITING,
+ I40E_NVMUPD_STATE_INIT_WAIT,
+ I40E_NVMUPD_STATE_WRITE_WAIT,
};
/* nvm_access definition and its masks/shifts need to be accessible to
@@ -385,6 +437,7 @@ enum i40e_nvmupd_state {
#define I40E_NVM_SA (I40E_NVM_SNT | I40E_NVM_LCB)
#define I40E_NVM_ERA 0x4
#define I40E_NVM_CSUM 0x8
+#define I40E_NVM_EXEC 0xf
#define I40E_NVM_ADAPT_SHIFT 16
#define I40E_NVM_ADAPT_MASK (0xffffULL << I40E_NVM_ADAPT_SHIFT)
@@ -465,6 +518,8 @@ struct i40e_fc_info {
#define I40E_APP_PROTOID_FIP 0x8914
#define I40E_APP_SEL_ETHTYPE 0x1
#define I40E_APP_SEL_TCPIP 0x2
+#define I40E_CEE_APP_SEL_ETHTYPE 0x0
+#define I40E_CEE_APP_SEL_TCPIP 0x1
/* CEE or IEEE 802.1Qaz ETS Configuration data */
struct i40e_dcb_ets_config {
@@ -496,6 +551,7 @@ struct i40e_dcbx_config {
#define I40E_DCBX_MODE_CEE 0x1
#define I40E_DCBX_MODE_IEEE 0x2
u32 numapps;
+ u32 tlv_status; /* CEE mode TLV status */
struct i40e_dcb_ets_config etscfg;
struct i40e_dcb_ets_config etsrec;
struct i40e_dcb_pfc_config pfc;
@@ -547,6 +603,8 @@ struct i40e_hw {
/* state of nvm update process */
enum i40e_nvmupd_state nvmupd_state;
+ struct i40e_aq_desc nvm_wb_desc;
+ struct i40e_virt_mem nvm_buff;
/* HMC info */
struct i40e_hmc_info hmc; /* HMC info struct */
@@ -555,16 +613,23 @@ struct i40e_hw {
u16 dcbx_status;
/* DCBX info */
- struct i40e_dcbx_config local_dcbx_config;
- struct i40e_dcbx_config remote_dcbx_config;
+ struct i40e_dcbx_config local_dcbx_config; /* Oper/Local Cfg */
+ struct i40e_dcbx_config remote_dcbx_config; /* Peer Cfg */
+ struct i40e_dcbx_config desired_dcbx_config; /* CEE Desired Cfg */
/* debug mask */
u32 debug_mask;
+ char err_str[16];
};
-static inline bool i40e_is_vf(struct i40e_hw *hw)
+static INLINE bool i40e_is_vf(struct i40e_hw *hw)
{
+#ifdef X722_SUPPORT
+ return (hw->mac.type == I40E_MAC_VF ||
+ hw->mac.type == I40E_MAC_X722_VF);
+#else
return hw->mac.type == I40E_MAC_VF;
+#endif
}
struct i40e_driver_version {
@@ -668,7 +733,11 @@ enum i40e_rx_desc_status_bits {
I40E_RX_DESC_STATUS_CRCP_SHIFT = 4,
I40E_RX_DESC_STATUS_TSYNINDX_SHIFT = 5, /* 2 BITS */
I40E_RX_DESC_STATUS_TSYNVALID_SHIFT = 7,
+#ifdef X722_SUPPORT
+ I40E_RX_DESC_STATUS_EXT_UDP_0_SHIFT = 8,
+#else
I40E_RX_DESC_STATUS_RESERVED1_SHIFT = 8,
+#endif
I40E_RX_DESC_STATUS_UMBCAST_SHIFT = 9, /* 2 BITS */
I40E_RX_DESC_STATUS_FLM_SHIFT = 11,
@@ -676,12 +745,16 @@ enum i40e_rx_desc_status_bits {
I40E_RX_DESC_STATUS_LPBK_SHIFT = 14,
I40E_RX_DESC_STATUS_IPV6EXADD_SHIFT = 15,
I40E_RX_DESC_STATUS_RESERVED2_SHIFT = 16, /* 2 BITS */
+#ifdef X722_SUPPORT
+ I40E_RX_DESC_STATUS_INT_UDP_0_SHIFT = 18,
+#else
I40E_RX_DESC_STATUS_UDP_0_SHIFT = 18,
+#endif
I40E_RX_DESC_STATUS_LAST /* this entry must be last!!! */
};
#define I40E_RXD_QW1_STATUS_SHIFT 0
-#define I40E_RXD_QW1_STATUS_MASK (((1 << I40E_RX_DESC_STATUS_LAST) - 1) << \
+#define I40E_RXD_QW1_STATUS_MASK ((BIT(I40E_RX_DESC_STATUS_LAST) - 1) << \
I40E_RXD_QW1_STATUS_SHIFT)
#define I40E_RXD_QW1_STATUS_TSYNINDX_SHIFT I40E_RX_DESC_STATUS_TSYNINDX_SHIFT
@@ -689,8 +762,7 @@ enum i40e_rx_desc_status_bits {
I40E_RXD_QW1_STATUS_TSYNINDX_SHIFT)
#define I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT I40E_RX_DESC_STATUS_TSYNVALID_SHIFT
-#define I40E_RXD_QW1_STATUS_TSYNVALID_MASK (0x1UL << \
- I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT)
+#define I40E_RXD_QW1_STATUS_TSYNVALID_MASK BIT_ULL(I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT)
#define I40E_RXD_QW1_STATUS_UMBCAST_SHIFT I40E_RX_DESC_STATUS_UMBCAST
#define I40E_RXD_QW1_STATUS_UMBCAST_MASK (0x3UL << \
@@ -836,8 +908,7 @@ enum i40e_rx_ptype_payload_layer {
I40E_RXD_QW1_LENGTH_HBUF_SHIFT)
#define I40E_RXD_QW1_LENGTH_SPH_SHIFT 63
-#define I40E_RXD_QW1_LENGTH_SPH_MASK (0x1ULL << \
- I40E_RXD_QW1_LENGTH_SPH_SHIFT)
+#define I40E_RXD_QW1_LENGTH_SPH_MASK BIT_ULL(I40E_RXD_QW1_LENGTH_SPH_SHIFT)
#define I40E_RXD_QW1_NEXTP_SHIFT 38
#define I40E_RXD_QW1_NEXTP_MASK (0x1FFFULL << I40E_RXD_QW1_NEXTP_SHIFT)
@@ -1040,12 +1111,11 @@ enum i40e_tx_ctx_desc_eipt_offload {
#define I40E_TXD_CTX_QW0_NATT_SHIFT 9
#define I40E_TXD_CTX_QW0_NATT_MASK (0x3ULL << I40E_TXD_CTX_QW0_NATT_SHIFT)
-#define I40E_TXD_CTX_UDP_TUNNELING (0x1ULL << I40E_TXD_CTX_QW0_NATT_SHIFT)
+#define I40E_TXD_CTX_UDP_TUNNELING BIT_ULL(I40E_TXD_CTX_QW0_NATT_SHIFT)
#define I40E_TXD_CTX_GRE_TUNNELING (0x2ULL << I40E_TXD_CTX_QW0_NATT_SHIFT)
#define I40E_TXD_CTX_QW0_EIP_NOINC_SHIFT 11
-#define I40E_TXD_CTX_QW0_EIP_NOINC_MASK (0x1ULL << \
- I40E_TXD_CTX_QW0_EIP_NOINC_SHIFT)
+#define I40E_TXD_CTX_QW0_EIP_NOINC_MASK BIT_ULL(I40E_TXD_CTX_QW0_EIP_NOINC_SHIFT)
#define I40E_TXD_CTX_EIP_NOINC_IPID_CONST I40E_TXD_CTX_QW0_EIP_NOINC_MASK
@@ -1057,6 +1127,10 @@ enum i40e_tx_ctx_desc_eipt_offload {
#define I40E_TXD_CTX_QW0_DECTTL_MASK (0xFULL << \
I40E_TXD_CTX_QW0_DECTTL_SHIFT)
+#ifdef X722_SUPPORT
+#define I40E_TXD_CTX_QW0_L4T_CS_SHIFT 23
+#define I40E_TXD_CTX_QW0_L4T_CS_MASK BIT_ULL(I40E_TXD_CTX_QW0_L4T_CS_SHIFT)
+#endif
struct i40e_nop_desc {
__le64 rsvd;
__le64 dtype_cmd;
@@ -1093,15 +1167,38 @@ struct i40e_filter_program_desc {
/* Packet Classifier Types for filters */
enum i40e_filter_pctype {
+#ifdef X722_SUPPORT
+ /* Note: Values 0-28 are reserved for future use.
+ * Value 29, 30, 32 are not supported on XL710 and X710.
+ */
+ I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP = 29,
+ I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP = 30,
+#else
/* Note: Values 0-30 are reserved for future use */
+#endif
I40E_FILTER_PCTYPE_NONF_IPV4_UDP = 31,
+#ifdef X722_SUPPORT
+ I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK = 32,
+#else
/* Note: Value 32 is reserved for future use */
+#endif
I40E_FILTER_PCTYPE_NONF_IPV4_TCP = 33,
I40E_FILTER_PCTYPE_NONF_IPV4_SCTP = 34,
I40E_FILTER_PCTYPE_NONF_IPV4_OTHER = 35,
I40E_FILTER_PCTYPE_FRAG_IPV4 = 36,
+#ifdef X722_SUPPORT
+ /* Note: Values 37-38 are reserved for future use.
+ * Value 39, 40, 42 are not supported on XL710 and X710.
+ */
+ I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP = 39,
+ I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP = 40,
+#else
/* Note: Values 37-40 are reserved for future use */
+#endif
I40E_FILTER_PCTYPE_NONF_IPV6_UDP = 41,
+#ifdef X722_SUPPORT
+ I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK = 42,
+#endif
I40E_FILTER_PCTYPE_NONF_IPV6_TCP = 43,
I40E_FILTER_PCTYPE_NONF_IPV6_SCTP = 44,
I40E_FILTER_PCTYPE_NONF_IPV6_OTHER = 45,
@@ -1128,8 +1225,7 @@ enum i40e_filter_program_desc_fd_status {
};
#define I40E_TXD_FLTR_QW0_DEST_VSI_SHIFT 23
-#define I40E_TXD_FLTR_QW0_DEST_VSI_MASK (0x1FFUL << \
- I40E_TXD_FLTR_QW0_DEST_VSI_SHIFT)
+#define I40E_TXD_FLTR_QW0_DEST_VSI_MASK BIT_ULL(I40E_TXD_FLTR_QW0_DEST_VSI_SHIFT)
#define I40E_TXD_FLTR_QW1_DTYPE_SHIFT 0
#define I40E_TXD_FLTR_QW1_DTYPE_MASK (0xFUL << I40E_TXD_FLTR_QW1_DTYPE_SHIFT)
@@ -1150,13 +1246,18 @@ enum i40e_filter_program_desc_pcmd {
#define I40E_TXD_FLTR_QW1_DEST_MASK (0x3ULL << I40E_TXD_FLTR_QW1_DEST_SHIFT)
#define I40E_TXD_FLTR_QW1_CNT_ENA_SHIFT (0x7ULL + I40E_TXD_FLTR_QW1_CMD_SHIFT)
-#define I40E_TXD_FLTR_QW1_CNT_ENA_MASK (0x1ULL << \
- I40E_TXD_FLTR_QW1_CNT_ENA_SHIFT)
+#define I40E_TXD_FLTR_QW1_CNT_ENA_MASK BIT_ULL(I40E_TXD_FLTR_QW1_CNT_ENA_SHIFT)
#define I40E_TXD_FLTR_QW1_FD_STATUS_SHIFT (0x9ULL + \
I40E_TXD_FLTR_QW1_CMD_SHIFT)
#define I40E_TXD_FLTR_QW1_FD_STATUS_MASK (0x3ULL << \
I40E_TXD_FLTR_QW1_FD_STATUS_SHIFT)
+#ifdef X722_SUPPORT
+
+#define I40E_TXD_FLTR_QW1_ATR_SHIFT (0xEULL + \
+ I40E_TXD_FLTR_QW1_CMD_SHIFT)
+#define I40E_TXD_FLTR_QW1_ATR_MASK BIT_ULL(I40E_TXD_FLTR_QW1_ATR_SHIFT)
+#endif
#define I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT 20
#define I40E_TXD_FLTR_QW1_CNTINDEX_MASK (0x1FFUL << \
@@ -1263,6 +1364,9 @@ struct i40e_hw_port_stats {
/* flow director stats */
u64 fd_atr_match;
u64 fd_sb_match;
+ u64 fd_atr_tunnel_match;
+ u32 fd_atr_status;
+ u32 fd_sb_status;
/* EEE LPI */
u32 tx_lpi_status;
u32 rx_lpi_status;
@@ -1288,6 +1392,7 @@ struct i40e_hw_port_stats {
#define I40E_SR_PBA_FLAGS 0x15
#define I40E_SR_PBA_BLOCK_PTR 0x16
#define I40E_SR_BOOT_CONFIG_PTR 0x17
+#define I40E_NVM_OEM_VER_OFF 0x83
#define I40E_SR_NVM_DEV_STARTER_VERSION 0x18
#define I40E_SR_NVM_WAKE_ON_LAN 0x19
#define I40E_SR_ALTERNATE_SAN_MAC_ADDRESS_PTR 0x27
diff --git a/sys/dev/ixl/i40e_virtchnl.h b/sys/dev/ixl/i40e_virtchnl.h
index 5a5e8f355cf9..9da33a0b425d 100644
--- a/sys/dev/ixl/i40e_virtchnl.h
+++ b/sys/dev/ixl/i40e_virtchnl.h
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2013-2014, Intel Corporation
+ Copyright (c) 2013-2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -89,7 +89,6 @@ enum i40e_virtchnl_ops {
I40E_VIRTCHNL_OP_GET_STATS = 15,
I40E_VIRTCHNL_OP_FCOE = 16,
I40E_VIRTCHNL_OP_EVENT = 17,
- I40E_VIRTCHNL_OP_CONFIG_RSS = 18,
};
/* Virtual channel message descriptor. This overlays the admin queue
@@ -118,7 +117,9 @@ struct i40e_virtchnl_msg {
* error regardless of version mismatch.
*/
#define I40E_VIRTCHNL_VERSION_MAJOR 1
-#define I40E_VIRTCHNL_VERSION_MINOR 0
+#define I40E_VIRTCHNL_VERSION_MINOR 1
+#define I40E_VIRTCHNL_VERSION_MINOR_NO_VF_CAPS 0
+
struct i40e_virtchnl_version_info {
u32 major;
u32 minor;
@@ -137,7 +138,8 @@ struct i40e_virtchnl_version_info {
*/
/* I40E_VIRTCHNL_OP_GET_VF_RESOURCES
- * VF sends this request to PF with no parameters
+ * Version 1.0 VF sends this request to PF with no parameters
+ * Version 1.1 VF sends this request to PF with u32 bitmap of its capabilities
* PF responds with an indirect message containing
* i40e_virtchnl_vf_resource and one or more
* i40e_virtchnl_vsi_resource structures.
@@ -151,10 +153,13 @@ struct i40e_virtchnl_vsi_resource {
u8 default_mac_addr[I40E_ETH_LENGTH_OF_ADDRESS];
};
/* VF offload flags */
-#define I40E_VIRTCHNL_VF_OFFLOAD_L2 0x00000001
-#define I40E_VIRTCHNL_VF_OFFLOAD_IWARP 0x00000002
-#define I40E_VIRTCHNL_VF_OFFLOAD_FCOE 0x00000004
-#define I40E_VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000
+#define I40E_VIRTCHNL_VF_OFFLOAD_L2 0x00000001
+#define I40E_VIRTCHNL_VF_OFFLOAD_IWARP 0x00000002
+#define I40E_VIRTCHNL_VF_OFFLOAD_FCOE 0x00000004
+#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ 0x00000008
+#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG 0x00000010
+#define I40E_VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000
+#define I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000
struct i40e_virtchnl_vf_resource {
u16 num_vsis;
diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c
index de4ee2450668..13a678cda7bc 100644
--- a/sys/dev/ixl/if_ixl.c
+++ b/sys/dev/ixl/if_ixl.c
@@ -48,7 +48,7 @@
/*********************************************************************
* Driver version
*********************************************************************/
-char ixl_driver_version[] = "1.4.1";
+char ixl_driver_version[] = "1.4.3";
/*********************************************************************
* PCI Device ID Table
@@ -70,7 +70,14 @@ static ixl_vendor_info_t ixl_vendor_info_array[] =
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_B, 0, 0, 0},
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_C, 0, 0, 0},
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T, 0, 0, 0},
+ {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T4, 0, 0, 0},
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_20G_KR2, 0, 0, 0},
+ {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_20G_KR2_A, 0, 0, 0},
+#ifdef X722_SUPPORT
+ {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_X722, 0, 0, 0},
+ {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_1G_BASE_T_X722, 0, 0, 0},
+ {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_X722, 0, 0, 0},
+#endif
/* required last entry */
{0, 0, 0, 0, 0}
};
@@ -199,8 +206,8 @@ static int ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS);
#ifdef PCI_IOV
static int ixl_adminq_err_to_errno(enum i40e_admin_queue_err err);
-static int ixl_init_iov(device_t dev, uint16_t num_vfs, const nvlist_t*);
-static void ixl_uninit_iov(device_t dev);
+static int ixl_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t*);
+static void ixl_iov_uninit(device_t dev);
static int ixl_add_vf(device_t dev, uint16_t vfnum, const nvlist_t*);
static void ixl_handle_vf_msg(struct ixl_pf *,
@@ -222,9 +229,9 @@ static device_method_t ixl_methods[] = {
DEVMETHOD(device_detach, ixl_detach),
DEVMETHOD(device_shutdown, ixl_shutdown),
#ifdef PCI_IOV
- DEVMETHOD(pci_init_iov, ixl_init_iov),
- DEVMETHOD(pci_uninit_iov, ixl_uninit_iov),
- DEVMETHOD(pci_add_vf, ixl_add_vf),
+ DEVMETHOD(pci_iov_init, ixl_iov_init),
+ DEVMETHOD(pci_iov_uninit, ixl_iov_uninit),
+ DEVMETHOD(pci_iov_add_vf, ixl_add_vf),
#endif
{0, 0}
};
@@ -238,12 +245,10 @@ DRIVER_MODULE(ixl, pci, ixl_driver, ixl_devclass, 0, 0);
MODULE_DEPEND(ixl, pci, 1, 1, 1);
MODULE_DEPEND(ixl, ether, 1, 1, 1);
-
#ifdef DEV_NETMAP
MODULE_DEPEND(ixl, netmap, 1, 1, 1);
#endif /* DEV_NETMAP */
-
/*
** Global reset mutex
*/
@@ -480,6 +485,22 @@ ixl_attach(device_t dev)
#ifdef IXL_DEBUG_SYSCTL
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, pf, 0,
+ ixl_debug_info, "I", "Debug Information");
+
+ /* Debug shared-code message level */
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "debug_mask", CTLFLAG_RW,
+ &pf->hw.debug_mask, 0, "Debug Message Level");
+
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "vc_debug_level", CTLFLAG_RW, &pf->vc_debug_lvl,
+ 0, "PF/VF Virtual Channel debug level");
+
+ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
OID_AUTO, "link_status", CTLTYPE_STRING | CTLFLAG_RD,
pf, 0, ixl_sysctl_link_status, "A", "Current Link Status");
@@ -525,13 +546,6 @@ ixl_attach(device_t dev)
goto err_out;
}
- /* Create for initial debugging use */
- SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
- SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
- OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, pf, 0,
- ixl_debug_info, "I", "Debug Information");
-
-
/* Establish a clean starting point */
i40e_clear_hw(hw);
error = i40e_pf_reset(hw);
@@ -642,7 +656,7 @@ ixl_attach(device_t dev)
/* Determine link state */
i40e_aq_get_link_info(hw, TRUE, NULL, NULL);
- pf->link_up = i40e_get_link_status(hw);
+ i40e_get_link_status(hw, &pf->link_up);
/* Setup OS specific network interface */
if (ixl_setup_interface(dev, vsi) != 0) {
@@ -702,7 +716,6 @@ ixl_attach(device_t dev)
#ifdef DEV_NETMAP
ixl_netmap_attach(vsi);
#endif /* DEV_NETMAP */
-
INIT_DEBUGOUT("ixl_attach: end");
return (0);
@@ -1053,6 +1066,9 @@ ixl_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
break;
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
+#ifdef IFM_ETH_XTYPE
+ case SIOCGIFXMEDIA:
+#endif
IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)");
error = ifmedia_ioctl(ifp, ifr, &vsi->media, command);
break;
@@ -1426,7 +1442,7 @@ ixl_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
IXL_PF_LOCK(pf);
hw->phy.get_link_info = TRUE;
- pf->link_up = i40e_get_link_status(hw);
+ i40e_get_link_status(hw, &pf->link_up);
ixl_update_link_status(pf);
ifmr->ifm_status = IFM_AVALID;
@@ -1457,12 +1473,7 @@ ixl_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
ifmr->ifm_active |= IFM_1000_LX;
break;
/* 10 G */
- case I40E_PHY_TYPE_10GBASE_CR1:
- case I40E_PHY_TYPE_10GBASE_CR1_CU:
case I40E_PHY_TYPE_10GBASE_SFPP_CU:
- /* Using this until a real KR media type */
- case I40E_PHY_TYPE_10GBASE_KR:
- case I40E_PHY_TYPE_10GBASE_KX4:
ifmr->ifm_active |= IFM_10G_TWINAX;
break;
case I40E_PHY_TYPE_10GBASE_SR:
@@ -1485,16 +1496,49 @@ ixl_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
case I40E_PHY_TYPE_40GBASE_LR4:
ifmr->ifm_active |= IFM_40G_LR4;
break;
- /*
- ** Set these to CR4 because OS does not
- ** have types available yet.
- */
+#ifndef IFM_ETH_XTYPE
+ case I40E_PHY_TYPE_1000BASE_KX:
+ ifmr->ifm_active |= IFM_1000_CX;
+ break;
+ case I40E_PHY_TYPE_10GBASE_CR1_CU:
+ case I40E_PHY_TYPE_10GBASE_CR1:
+ ifmr->ifm_active |= IFM_10G_TWINAX;
+ break;
+ case I40E_PHY_TYPE_10GBASE_KX4:
+ ifmr->ifm_active |= IFM_10G_CX4;
+ break;
+ case I40E_PHY_TYPE_10GBASE_KR:
+ ifmr->ifm_active |= IFM_10G_SR;
+ break;
case I40E_PHY_TYPE_40GBASE_KR4:
- case I40E_PHY_TYPE_XLAUI:
case I40E_PHY_TYPE_XLPPI:
- case I40E_PHY_TYPE_40GBASE_AOC:
- ifmr->ifm_active |= IFM_40G_CR4;
+ ifmr->ifm_active |= IFM_40G_SR4;
+ break;
+#else
+ case I40E_PHY_TYPE_1000BASE_KX:
+ ifmr->ifm_active |= IFM_1000_KX;
+ break;
+ /* ERJ: What's the difference between these? */
+ case I40E_PHY_TYPE_10GBASE_CR1_CU:
+ case I40E_PHY_TYPE_10GBASE_CR1:
+ ifmr->ifm_active |= IFM_10G_CR1;
+ break;
+ case I40E_PHY_TYPE_10GBASE_KX4:
+ ifmr->ifm_active |= IFM_10G_KX4;
+ break;
+ case I40E_PHY_TYPE_10GBASE_KR:
+ ifmr->ifm_active |= IFM_10G_KR;
+ break;
+ case I40E_PHY_TYPE_20GBASE_KR2:
+ ifmr->ifm_active |= IFM_20G_KR2;
+ break;
+ case I40E_PHY_TYPE_40GBASE_KR4:
+ ifmr->ifm_active |= IFM_40G_KR4;
+ break;
+ case I40E_PHY_TYPE_XLPPI:
+ ifmr->ifm_active |= IFM_40G_XLPPI;
break;
+#endif
default:
ifmr->ifm_active |= IFM_UNKNOWN;
break;
@@ -2417,13 +2461,8 @@ ixl_add_ifmedia(struct ixl_vsi *vsi, u32 phy_type)
if (phy_type & (1 << I40E_PHY_TYPE_1000BASE_LX))
ifmedia_add(&vsi->media, IFM_ETHER | IFM_1000_LX, 0, NULL);
- if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_CR1_CU) ||
- phy_type & (1 << I40E_PHY_TYPE_10GBASE_KX4) ||
- phy_type & (1 << I40E_PHY_TYPE_10GBASE_KR) ||
- phy_type & (1 << I40E_PHY_TYPE_10GBASE_AOC) ||
- phy_type & (1 << I40E_PHY_TYPE_XAUI) ||
+ if (phy_type & (1 << I40E_PHY_TYPE_XAUI) ||
phy_type & (1 << I40E_PHY_TYPE_XFI) ||
- phy_type & (1 << I40E_PHY_TYPE_SFI) ||
phy_type & (1 << I40E_PHY_TYPE_10GBASE_SFPP_CU))
ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_TWINAX, 0, NULL);
@@ -2438,15 +2477,55 @@ ixl_add_ifmedia(struct ixl_vsi *vsi, u32 phy_type)
phy_type & (1 << I40E_PHY_TYPE_40GBASE_CR4_CU) ||
phy_type & (1 << I40E_PHY_TYPE_40GBASE_AOC) ||
phy_type & (1 << I40E_PHY_TYPE_XLAUI) ||
- phy_type & (1 << I40E_PHY_TYPE_XLPPI) ||
- /* KR4 uses CR4 until the OS has the real media type */
phy_type & (1 << I40E_PHY_TYPE_40GBASE_KR4))
ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_CR4, 0, NULL);
-
if (phy_type & (1 << I40E_PHY_TYPE_40GBASE_SR4))
ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_SR4, 0, NULL);
if (phy_type & (1 << I40E_PHY_TYPE_40GBASE_LR4))
ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_LR4, 0, NULL);
+
+#ifndef IFM_ETH_XTYPE
+ if (phy_type & (1 << I40E_PHY_TYPE_1000BASE_KX))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_1000_CX, 0, NULL);
+
+ if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_CR1_CU) ||
+ phy_type & (1 << I40E_PHY_TYPE_10GBASE_CR1) ||
+ phy_type & (1 << I40E_PHY_TYPE_10GBASE_AOC) ||
+ phy_type & (1 << I40E_PHY_TYPE_SFI))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_TWINAX, 0, NULL);
+ if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_KX4))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_CX4, 0, NULL);
+ if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_KR))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_SR, 0, NULL);
+
+ if (phy_type & (1 << I40E_PHY_TYPE_40GBASE_KR4))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_SR4, 0, NULL);
+ if (phy_type & (1 << I40E_PHY_TYPE_XLPPI))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_CR4, 0, NULL);
+#else
+ if (phy_type & (1 << I40E_PHY_TYPE_1000BASE_KX))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_1000_KX, 0, NULL);
+
+ if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_CR1_CU)
+ || phy_type & (1 << I40E_PHY_TYPE_10GBASE_CR1))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_CR1, 0, NULL);
+ if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_AOC))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_TWINAX_LONG, 0, NULL);
+ if (phy_type & (1 << I40E_PHY_TYPE_SFI))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_SFI, 0, NULL);
+ if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_KX4))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_KX4, 0, NULL);
+ if (phy_type & (1 << I40E_PHY_TYPE_10GBASE_KR))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_10G_KR, 0, NULL);
+
+ if (phy_type & (1 << I40E_PHY_TYPE_20GBASE_KR2))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_20G_KR2, 0, NULL);
+
+ if (phy_type & (1 << I40E_PHY_TYPE_40GBASE_KR4))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_KR4, 0, NULL);
+ if (phy_type & (1 << I40E_PHY_TYPE_XLPPI))
+ ifmedia_add(&vsi->media, IFM_ETHER | IFM_40G_XLPPI, 0, NULL);
+#endif
}
/*********************************************************************
@@ -2569,7 +2648,7 @@ ixl_link_event(struct ixl_pf *pf, struct i40e_arq_event_info *e)
bool check;
hw->phy.get_link_info = TRUE;
- check = i40e_get_link_status(hw);
+ i40e_get_link_status(hw, &check);
pf->link_up = check;
#ifdef IXL_DEBUG
printf("Link is %s\n", check ? "up":"down");
@@ -3184,10 +3263,6 @@ ixl_add_hw_stats(struct ixl_pf *pf)
CTLFLAG_RD, &pf->admin_irq,
"Admin Queue IRQ Handled");
- SYSCTL_ADD_INT(ctx, child, OID_AUTO, "vc_debug_level",
- CTLFLAG_RW, &pf->vc_debug_lvl, 0,
- "PF/VF Virtual Channel debug logging level");
-
ixl_add_vsi_sysctls(pf, &pf->vsi, ctx, "pf");
vsi_list = SYSCTL_CHILDREN(pf->vsi.vsi_node);
@@ -3331,6 +3406,7 @@ ixl_add_sysctls_mac_stats(struct sysctl_ctx_list *ctx,
}
}
+
/*
** ixl_config_rss - setup RSS
** - note this is done for the single vsi
@@ -4976,8 +5052,8 @@ static int
ixl_res_alloc_cmp(const void *a, const void *b)
{
const struct i40e_aqc_switch_resource_alloc_element_resp *one, *two;
- one = (struct i40e_aqc_switch_resource_alloc_element_resp *)a;
- two = (struct i40e_aqc_switch_resource_alloc_element_resp *)b;
+ one = (const struct i40e_aqc_switch_resource_alloc_element_resp *)a;
+ two = (const struct i40e_aqc_switch_resource_alloc_element_resp *)b;
return ((int)one->resource_type - (int)two->resource_type);
}
@@ -4994,7 +5070,7 @@ ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS)
u8 num_entries;
struct i40e_aqc_switch_resource_alloc_element_resp resp[IXL_SW_RES_SIZE];
- buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
+ buf = sbuf_new_for_sysctl(NULL, NULL, 0, req);
if (!buf) {
device_printf(dev, "Could not allocate sbuf for output.\n");
return (ENOMEM);
@@ -5038,7 +5114,13 @@ ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS)
error = sbuf_finish(buf);
if (error) {
device_printf(dev, "Error finishing sbuf: %d\n", error);
+ sbuf_delete(buf);
+ return error;
}
+
+ error = sysctl_handle_string(oidp, sbuf_data(buf), sbuf_len(buf), req);
+ if (error)
+ device_printf(dev, "sysctl error: %d\n", error);
sbuf_delete(buf);
return error;
}
@@ -5096,7 +5178,7 @@ ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS)
struct i40e_aqc_get_switch_config_resp *sw_config;
sw_config = (struct i40e_aqc_get_switch_config_resp *)aq_buf;
- buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
+ buf = sbuf_new_for_sysctl(NULL, NULL, 0, req);
if (!buf) {
device_printf(dev, "Could not allocate sbuf for sysctl output.\n");
return (ENOMEM);
@@ -5115,7 +5197,6 @@ ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS)
nmbuf = sbuf_new_auto();
if (!nmbuf) {
device_printf(dev, "Could not allocate sbuf for name output.\n");
- sbuf_delete(buf);
return (ENOMEM);
}
@@ -5150,7 +5231,13 @@ ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS)
error = sbuf_finish(buf);
if (error) {
device_printf(dev, "Error finishing sbuf: %d\n", error);
+ sbuf_delete(buf);
+ return error;
}
+
+ error = sysctl_handle_string(oidp, sbuf_data(buf), sbuf_len(buf), req);
+ if (error)
+ device_printf(dev, "sysctl error: %d\n", error);
sbuf_delete(buf);
return (error);
@@ -6456,7 +6543,7 @@ ixl_adminq_err_to_errno(enum i40e_admin_queue_err err)
}
static int
-ixl_init_iov(device_t dev, uint16_t num_vfs, const nvlist_t *params)
+ixl_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *params)
{
struct ixl_pf *pf;
struct i40e_hw *hw;
@@ -6504,7 +6591,7 @@ fail:
}
static void
-ixl_uninit_iov(device_t dev)
+ixl_iov_uninit(device_t dev)
{
struct ixl_pf *pf;
struct i40e_hw *hw;
diff --git a/sys/dev/ixl/if_ixlv.c b/sys/dev/ixl/if_ixlv.c
index fe4c63f85bfe..51d4e9529654 100644
--- a/sys/dev/ixl/if_ixlv.c
+++ b/sys/dev/ixl/if_ixlv.c
@@ -48,7 +48,7 @@
/*********************************************************************
* Driver version
*********************************************************************/
-char ixlv_driver_version[] = "1.2.4";
+char ixlv_driver_version[] = "1.2.6";
/*********************************************************************
* PCI Device ID Table
@@ -1832,7 +1832,7 @@ ixlv_msix_adminq(void *arg)
mask = rd32(hw, I40E_VFINT_ICR0_ENA1);
reg = rd32(hw, I40E_VFINT_DYN_CTL01);
- reg |= I40E_PFINT_DYN_CTL0_CLEARPBA_MASK;
+ reg |= I40E_VFINT_DYN_CTL01_CLEARPBA_MASK;
wr32(hw, I40E_VFINT_DYN_CTL01, reg);
/* schedule task */
@@ -1879,7 +1879,7 @@ ixlv_enable_adminq_irq(struct i40e_hw *hw)
wr32(hw, I40E_VFINT_DYN_CTL01,
I40E_VFINT_DYN_CTL01_INTENA_MASK |
I40E_VFINT_DYN_CTL01_ITR_INDX_MASK);
- wr32(hw, I40E_VFINT_ICR0_ENA1, I40E_VFINT_ICR0_ENA_ADMINQ_MASK);
+ wr32(hw, I40E_VFINT_ICR0_ENA1, I40E_VFINT_ICR0_ENA1_ADMINQ_MASK);
/* flush */
rd32(hw, I40E_VFGEN_RSTAT);
return;
@@ -1891,7 +1891,7 @@ ixlv_enable_queue_irq(struct i40e_hw *hw, int id)
u32 reg;
reg = I40E_VFINT_DYN_CTLN1_INTENA_MASK |
- I40E_VFINT_DYN_CTLN_CLEARPBA_MASK;
+ I40E_VFINT_DYN_CTLN1_CLEARPBA_MASK;
wr32(hw, I40E_VFINT_DYN_CTLN1(id), reg);
}
@@ -2375,8 +2375,8 @@ ixlv_local_timer(void *arg)
/*
** Check status on the queues for a hang
*/
- mask = (I40E_VFINT_DYN_CTLN_INTENA_MASK |
- I40E_VFINT_DYN_CTLN_SWINT_TRIG_MASK);
+ mask = (I40E_VFINT_DYN_CTLN1_INTENA_MASK |
+ I40E_VFINT_DYN_CTLN1_SWINT_TRIG_MASK);
for (int i = 0; i < vsi->num_queues; i++,que++) {
/* Any queues with outstanding work get a sw irq */
@@ -2742,33 +2742,33 @@ ixlv_do_adminq_locked(struct ixlv_sc *sc)
/* check for Admin queue errors */
oldreg = reg = rd32(hw, hw->aq.arq.len);
- if (reg & I40E_VF_ARQLEN_ARQVFE_MASK) {
+ if (reg & I40E_VF_ARQLEN1_ARQVFE_MASK) {
device_printf(dev, "ARQ VF Error detected\n");
- reg &= ~I40E_VF_ARQLEN_ARQVFE_MASK;
+ reg &= ~I40E_VF_ARQLEN1_ARQVFE_MASK;
}
- if (reg & I40E_VF_ARQLEN_ARQOVFL_MASK) {
+ if (reg & I40E_VF_ARQLEN1_ARQOVFL_MASK) {
device_printf(dev, "ARQ Overflow Error detected\n");
- reg &= ~I40E_VF_ARQLEN_ARQOVFL_MASK;
+ reg &= ~I40E_VF_ARQLEN1_ARQOVFL_MASK;
}
- if (reg & I40E_VF_ARQLEN_ARQCRIT_MASK) {
+ if (reg & I40E_VF_ARQLEN1_ARQCRIT_MASK) {
device_printf(dev, "ARQ Critical Error detected\n");
- reg &= ~I40E_VF_ARQLEN_ARQCRIT_MASK;
+ reg &= ~I40E_VF_ARQLEN1_ARQCRIT_MASK;
}
if (oldreg != reg)
wr32(hw, hw->aq.arq.len, reg);
oldreg = reg = rd32(hw, hw->aq.asq.len);
- if (reg & I40E_VF_ATQLEN_ATQVFE_MASK) {
+ if (reg & I40E_VF_ATQLEN1_ATQVFE_MASK) {
device_printf(dev, "ASQ VF Error detected\n");
- reg &= ~I40E_VF_ATQLEN_ATQVFE_MASK;
+ reg &= ~I40E_VF_ATQLEN1_ATQVFE_MASK;
}
- if (reg & I40E_VF_ATQLEN_ATQOVFL_MASK) {
+ if (reg & I40E_VF_ATQLEN1_ATQOVFL_MASK) {
device_printf(dev, "ASQ Overflow Error detected\n");
- reg &= ~I40E_VF_ATQLEN_ATQOVFL_MASK;
+ reg &= ~I40E_VF_ATQLEN1_ATQOVFL_MASK;
}
- if (reg & I40E_VF_ATQLEN_ATQCRIT_MASK) {
+ if (reg & I40E_VF_ATQLEN1_ATQCRIT_MASK) {
device_printf(dev, "ASQ Critical Error detected\n");
- reg &= ~I40E_VF_ATQLEN_ATQCRIT_MASK;
+ reg &= ~I40E_VF_ATQLEN1_ATQCRIT_MASK;
}
if (oldreg != reg)
wr32(hw, hw->aq.asq.len, reg);
diff --git a/sys/dev/ixl/ixl.h b/sys/dev/ixl/ixl.h
index 1ddfbca3d7d7..3348e1abae27 100644
--- a/sys/dev/ixl/ixl.h
+++ b/sys/dev/ixl/ixl.h
@@ -93,6 +93,7 @@
#ifdef PCI_IOV
#include <sys/nv.h>
#include <sys/iov_schema.h>
+#include <dev/pci/pci_iov.h>
#endif
#include "i40e_type.h"
diff --git a/sys/dev/ixl/ixlv.h b/sys/dev/ixl/ixlv.h
index 840e17af71da..695b1efb15da 100644
--- a/sys/dev/ixl/ixlv.h
+++ b/sys/dev/ixl/ixlv.h
@@ -117,6 +117,7 @@ struct ixlv_sc {
struct ifmedia media;
struct callout timer;
int msix;
+ int pf_version;
int if_flags;
bool link_up;
diff --git a/sys/dev/ixl/ixlvc.c b/sys/dev/ixl/ixlvc.c
index 02192f3f00c7..9333b6050d79 100644
--- a/sys/dev/ixl/ixlvc.c
+++ b/sys/dev/ixl/ixlvc.c
@@ -249,9 +249,12 @@ ixlv_verify_api_ver(struct ixlv_sc *sc)
}
pf_vvi = (struct i40e_virtchnl_version_info *)event.msg_buf;
- if ((pf_vvi->major != I40E_VIRTCHNL_VERSION_MAJOR) ||
- (pf_vvi->minor != I40E_VIRTCHNL_VERSION_MINOR))
+ if ((pf_vvi->major > I40E_VIRTCHNL_VERSION_MAJOR) ||
+ ((pf_vvi->major == I40E_VIRTCHNL_VERSION_MAJOR) &&
+ (pf_vvi->minor > I40E_VIRTCHNL_VERSION_MINOR)))
err = EIO;
+ else
+ sc->pf_version = pf_vvi->minor;
out_alloc:
free(event.msg_buf, M_DEVBUF);
@@ -269,7 +272,18 @@ out:
int
ixlv_send_vf_config_msg(struct ixlv_sc *sc)
{
- return ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
+ u32 caps;
+
+ caps = I40E_VIRTCHNL_VF_OFFLOAD_L2 |
+ I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ |
+ I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG |
+ I40E_VIRTCHNL_VF_OFFLOAD_VLAN;
+
+ if (sc->pf_version)
+ return ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
+ (u8 *)&caps, sizeof(caps));
+ else
+ return ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
NULL, 0);
}
diff --git a/sys/dev/led/led.c b/sys/dev/led/led.c
index fe0b66b8782e..c519e2218ece 100644
--- a/sys/dev/led/led.c
+++ b/sys/dev/led/led.c
@@ -293,7 +293,8 @@ led_create_state(led_t *func, void *priv, char const *name, int state)
mtx_lock(&led_mtx);
sc->dev->si_drv1 = sc;
LIST_INSERT_HEAD(&led_list, sc, list);
- sc->func(sc->private, state != 0);
+ if (state != -1)
+ sc->func(sc->private, state != 0);
mtx_unlock(&led_mtx);
return (sc->dev);
diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c
index a3aa04eea913..741837949909 100644
--- a/sys/dev/malo/if_malo.c
+++ b/sys/dev/malo/if_malo.c
@@ -133,7 +133,7 @@ static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *);
static void malo_start(struct ifnet *);
static void malo_watchdog(void *);
static int malo_ioctl(struct ifnet *, u_long, caddr_t);
-static void malo_updateslot(struct ifnet *);
+static void malo_updateslot(struct ieee80211com *);
static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void malo_scan_start(struct ieee80211com *);
static void malo_scan_end(struct ieee80211com *);
@@ -276,6 +276,8 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(sc->malo_dev);
/* XXX not right but it's not used anywhere important */
ic->ic_phytype = IEEE80211_T_OFDM;
ic->ic_opmode = IEEE80211_M_STA;
@@ -1764,15 +1766,14 @@ malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
* like slot time and preamble.
*/
static void
-malo_updateslot(struct ifnet *ifp)
+malo_updateslot(struct ieee80211com *ic)
{
- struct malo_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct malo_softc *sc = ic->ic_softc;
struct malo_hal *mh = sc->malo_mh;
int error;
/* NB: can be called early; suppress needless cmds */
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
DPRINTF(sc, MALO_DEBUG_RESET,
diff --git a/sys/dev/mfi/mfi.c b/sys/dev/mfi/mfi.c
index a2d604cf3f5d..ddcc853e9ad3 100644
--- a/sys/dev/mfi/mfi.c
+++ b/sys/dev/mfi/mfi.c
@@ -369,6 +369,7 @@ mfi_attach(struct mfi_softc *sc)
int error, commsz, framessz, sensesz;
int frames, unit, max_fw_sge, max_fw_cmds;
uint32_t tb_mem_size = 0;
+ struct cdev *dev_t;
if (sc == NULL)
return EINVAL;
@@ -763,7 +764,8 @@ mfi_attach(struct mfi_softc *sc)
sc->mfi_cdev = make_dev(&mfi_cdevsw, unit, UID_ROOT, GID_OPERATOR,
0640, "mfi%d", unit);
if (unit == 0)
- make_dev_alias(sc->mfi_cdev, "megaraid_sas_ioctl_node");
+ make_dev_alias_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &dev_t,
+ sc->mfi_cdev, "%s", "megaraid_sas_ioctl_node");
if (sc->mfi_cdev != NULL)
sc->mfi_cdev->si_drv1 = sc;
SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->mfi_dev),
diff --git a/sys/dev/mmc/mmcsd.c b/sys/dev/mmc/mmcsd.c
index 3be21585a105..4ca0c2492797 100644
--- a/sys/dev/mmc/mmcsd.c
+++ b/sys/dev/mmc/mmcsd.c
@@ -163,33 +163,10 @@ mmcsd_attach(device_t dev)
d->d_sectorsize = mmc_get_sector_size(dev);
d->d_maxsize = mmc_get_max_data(dev) * d->d_sectorsize;
d->d_mediasize = (off_t)mmc_get_media_size(dev) * d->d_sectorsize;
- d->d_stripeoffset = 0;
d->d_stripesize = mmc_get_erase_sector(dev) * d->d_sectorsize;
d->d_unit = device_get_unit(dev);
d->d_flags = DISKFLAG_CANDELETE;
- d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize * 1; /* conservative */
- /*
- * The d_fw* values are fake. However, layout is aided by making the
- * number of fwsectors equal to the erase sectors from the drive since
- * we set the stripe size equal to that. We set fwheads such that there
- * are ~20 cylinder groups since all values are somewhat arbitrary here
- * and this gives good behavior with ffs without wasting too much
- * space. Sadly, geom_part wants to round partitions to these
- * values. While not bad, in and of itself, the values we present here
- * will almost certainly be different then the values that USB SD
- * adapters use and there's too much variation between brands to just
- * use those values here. Also SD to ATA adapters favor traditional
- * ata sizes, which are different again from the USB adapters (which
- * favor SCSI values). This rounding leads to a loss of up to 5% of the
- * usable space (usually much less, but that's why 20 was selected: to
- * limit this effect at a few percent). gpart needs a way to override
- * this behavior for situations like this, but doesn't provide
- * one. Perhaps this behavior should be tunable as well, but maybe that
- * belongs in the disk layer. These values will be much better than
- * the default ones.
- */
- d->d_fwsectors = mmc_get_erase_sector(dev);
- d->d_fwheads = mmc_get_media_size(dev) / (d->d_fwsectors * 20);
+ d->d_delmaxsize = mmc_get_erase_sector(dev) * d->d_sectorsize;
strlcpy(d->d_ident, mmc_get_card_sn_string(dev), sizeof(d->d_ident));
strlcpy(d->d_descr, mmc_get_card_id_string(dev), sizeof(d->d_descr));
diff --git a/sys/dev/mpr/mpi/mpi2.h b/sys/dev/mpr/mpi/mpi2.h
index 10f17aba067e..42fdec20c503 100644
--- a/sys/dev/mpr/mpi/mpi2.h
+++ b/sys/dev/mpr/mpi/mpi2.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2013 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2.h
diff --git a/sys/dev/mpr/mpi/mpi2_cnfg.h b/sys/dev/mpr/mpi/mpi2_cnfg.h
index d82750f80913..3b0eb637a9e2 100644
--- a/sys/dev/mpr/mpi/mpi2_cnfg.h
+++ b/sys/dev/mpr/mpi/mpi2_cnfg.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2013 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_cnfg.h
diff --git a/sys/dev/mpr/mpi/mpi2_hbd.h b/sys/dev/mpr/mpi/mpi2_hbd.h
index d0cc09f905a0..520407b39948 100644
--- a/sys/dev/mpr/mpi/mpi2_hbd.h
+++ b/sys/dev/mpr/mpi/mpi2_hbd.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2009-2011 LSI Corporation.
+ * Copyright (c) 2009-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_hbd.h
diff --git a/sys/dev/mpr/mpi/mpi2_history.txt b/sys/dev/mpr/mpi/mpi2_history.txt
index 296b75b87859..9fca7966f65a 100644
--- a/sys/dev/mpr/mpi/mpi2_history.txt
+++ b/sys/dev/mpr/mpi/mpi2_history.txt
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@@ -35,7 +36,8 @@
Fusion-MPT MPI 2.0 / 2.5 Header File Change History
==============================
- Copyright (c) 2000-2013 LSI Corporation.
+ Copyright (c) 2000-2015 LSI Corporation.
+ Copyright (c) 2013-2015 Avago Technologies
---------------------------------------
Header Set Release Version: 02.00.33
diff --git a/sys/dev/mpr/mpi/mpi2_init.h b/sys/dev/mpr/mpi/mpi2_init.h
index 62b0cfed120a..5f475c0e26ba 100644
--- a/sys/dev/mpr/mpi/mpi2_init.h
+++ b/sys/dev/mpr/mpi/mpi2_init.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2013 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_init.h
diff --git a/sys/dev/mpr/mpi/mpi2_ioc.h b/sys/dev/mpr/mpi/mpi2_ioc.h
index 38a46f5280bc..54f39a5adc71 100644
--- a/sys/dev/mpr/mpi/mpi2_ioc.h
+++ b/sys/dev/mpr/mpi/mpi2_ioc.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2013 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_ioc.h
diff --git a/sys/dev/mpr/mpi/mpi2_ra.h b/sys/dev/mpr/mpi/mpi2_ra.h
index 76db06b71b98..02304aaa002e 100644
--- a/sys/dev/mpr/mpi/mpi2_ra.h
+++ b/sys/dev/mpr/mpi/mpi2_ra.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2009 LSI Corporation.
+ * Copyright (c) 2012-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_ra.h
diff --git a/sys/dev/mpr/mpi/mpi2_raid.h b/sys/dev/mpr/mpi/mpi2_raid.h
index c6bb59864a3c..52ebf07ee096 100644
--- a/sys/dev/mpr/mpi/mpi2_raid.h
+++ b/sys/dev/mpr/mpi/mpi2_raid.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2013 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_raid.h
diff --git a/sys/dev/mpr/mpi/mpi2_sas.h b/sys/dev/mpr/mpi/mpi2_sas.h
index 2a107f1e1617..7cae2c3d4adf 100644
--- a/sys/dev/mpr/mpi/mpi2_sas.h
+++ b/sys/dev/mpr/mpi/mpi2_sas.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2013 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_sas.h
diff --git a/sys/dev/mpr/mpi/mpi2_targ.h b/sys/dev/mpr/mpi/mpi2_targ.h
index 506e64f6370c..85b5ac562610 100644
--- a/sys/dev/mpr/mpi/mpi2_targ.h
+++ b/sys/dev/mpr/mpi/mpi2_targ.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2012 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_targ.h
diff --git a/sys/dev/mpr/mpi/mpi2_tool.h b/sys/dev/mpr/mpi/mpi2_tool.h
index 94542cc7959b..59917c0077f5 100644
--- a/sys/dev/mpr/mpi/mpi2_tool.h
+++ b/sys/dev/mpr/mpi/mpi2_tool.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2013 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_tool.h
diff --git a/sys/dev/mpr/mpi/mpi2_type.h b/sys/dev/mpr/mpi/mpi2_type.h
index da3aefb968f4..b063683263d0 100644
--- a/sys/dev/mpr/mpi/mpi2_type.h
+++ b/sys/dev/mpr/mpi/mpi2_type.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2013 LSI Corp.
+ * Copyright (c) 2012-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,13 +27,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
/*
- * Copyright (c) 2000-2007 LSI Corporation.
+ * Copyright (c) 2000-2015 LSI Corporation.
+ * Copyright (c) 2013-2015 Avago Technologies
*
*
* Name: mpi2_type.h
diff --git a/sys/dev/mpr/mpr.c b/sys/dev/mpr/mpr.c
index d3fb9a0682b8..07e73c54e8be 100644
--- a/sys/dev/mpr/mpr.c
+++ b/sys/dev/mpr/mpr.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
- * Copyright (c) 2012-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,12 +25,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
+ *
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-/* Communications core for LSI MPT2 */
+/* Communications core for Avago Technologies (LSI) MPT3 */
/* TODO Move headers to mprvar */
#include <sys/types.h>
@@ -72,7 +75,6 @@ __FBSDID("$FreeBSD$");
#include <dev/mpr/mpr_ioctl.h>
#include <dev/mpr/mprvar.h>
#include <dev/mpr/mpr_table.h>
-#include <dev/mpr/mpr_sas.h>
static int mpr_diag_reset(struct mpr_softc *sc, int sleep_flag);
static int mpr_init_queues(struct mpr_softc *sc);
@@ -352,11 +354,9 @@ mpr_transition_operational(struct mpr_softc *sc)
static int
mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
{
- int error, i;
+ int error;
Mpi2IOCFactsReply_t saved_facts;
uint8_t saved_mode, reallocating;
- struct mprsas_lun *lun, *lun_tmp;
- struct mprsas_target *targ;
mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
@@ -513,27 +513,7 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
*/
if (reallocating) {
mpr_iocfacts_free(sc);
-
- /*
- * The number of targets is based on IOC Facts, so free all of
- * the allocated LUNs for each target and then the target buffer
- * itself.
- */
- for (i=0; i< saved_facts.MaxTargets; i++) {
- targ = &sc->sassc->targets[i];
- SLIST_FOREACH_SAFE(lun, &targ->luns, lun_link,
- lun_tmp) {
- free(lun, M_MPR);
- }
- }
- free(sc->sassc->targets, M_MPR);
-
- sc->sassc->targets = malloc(sizeof(struct mprsas_target) *
- sc->facts->MaxTargets, M_MPR, M_WAITOK|M_ZERO);
- if (!sc->sassc->targets) {
- panic("%s failed to alloc targets with error %d\n",
- __func__, ENOMEM);
- }
+ mprsas_realloc_targets(sc, saved_facts.MaxTargets);
}
/*
@@ -775,7 +755,7 @@ mpr_reinit(struct mpr_softc *sc)
/* the end of discovery will release the simq, so we're done. */
mpr_dprint(sc, MPR_INFO, "%s finished sc %p post %u free %u\n",
__func__, sc, sc->replypostindex, sc->replyfreeindex);
- mprsas_release_simq_reinit(sassc);
+ mprsas_release_simq_reinit(sassc);
return 0;
}
@@ -816,7 +796,8 @@ mpr_wait_db_ack(struct mpr_softc *sc, int timeout, int sleep_flag)
* 0.5 milisecond
*/
if (mtx_owned(&sc->mpr_mtx) && sleep_flag == CAN_SLEEP)
- msleep(&sc->msleep_fake_chan, &sc->mpr_mtx, 0, "mprdba", hz/1000);
+ msleep(&sc->msleep_fake_chan, &sc->mpr_mtx, 0, "mprdba",
+ hz/1000);
else if (sleep_flag == CAN_SLEEP)
pause("mprdba", hz/1000);
else
@@ -982,7 +963,7 @@ mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm)
reply_descriptor rd;
MPR_FUNCTRACE(sc);
- mpr_dprint(sc, MPR_TRACE, "%s SMID %u cm %p ccb %p\n", __func__,
+ mpr_dprint(sc, MPR_TRACE, "SMID %u cm %p ccb %p\n",
cm->cm_desc.Default.SMID, cm, cm->cm_ccb);
if (sc->mpr_flags & MPR_FLAGS_ATTACH_DONE && !(sc->mpr_flags &
@@ -1372,6 +1353,8 @@ mpr_get_tunables(struct mpr_softc *sc)
sc->disable_msix = 0;
sc->disable_msi = 0;
sc->max_chains = MPR_CHAIN_FRAMES;
+ sc->enable_ssu = MPR_SSU_ENABLE_SSD_DISABLE_HDD;
+ sc->spinup_wait_time = DEFAULT_SPINUP_WAIT;
/*
* Grab the global variables.
@@ -1380,6 +1363,8 @@ mpr_get_tunables(struct mpr_softc *sc)
TUNABLE_INT_FETCH("hw.mpr.disable_msix", &sc->disable_msix);
TUNABLE_INT_FETCH("hw.mpr.disable_msi", &sc->disable_msi);
TUNABLE_INT_FETCH("hw.mpr.max_chains", &sc->max_chains);
+ TUNABLE_INT_FETCH("hw.mpr.enable_ssu", &sc->enable_ssu);
+ TUNABLE_INT_FETCH("hw.mpr.spinup_wait_time", &sc->spinup_wait_time);
/* Grab the unit-instance variables */
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.debug_level",
@@ -1402,6 +1387,14 @@ mpr_get_tunables(struct mpr_softc *sc)
snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.exclude_ids",
device_get_unit(sc->mpr_dev));
TUNABLE_STR_FETCH(tmpstr, sc->exclude_ids, sizeof(sc->exclude_ids));
+
+ snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.enable_ssu",
+ device_get_unit(sc->mpr_dev));
+ TUNABLE_INT_FETCH(tmpstr, &sc->enable_ssu);
+
+ snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.spinup_wait_time",
+ device_get_unit(sc->mpr_dev));
+ TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time);
}
static void
@@ -1474,11 +1467,20 @@ mpr_setup_sysctl(struct mpr_softc *sc)
OID_AUTO, "max_chains", CTLFLAG_RD,
&sc->max_chains, 0,"maximum chain frames that will be allocated");
+ SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+ OID_AUTO, "enable_ssu", CTLFLAG_RW, &sc->enable_ssu, 0,
+ "enable SSU to SATA SSD/HDD at shutdown");
+
#if __FreeBSD_version >= 900030
SYSCTL_ADD_UQUAD(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
OID_AUTO, "chain_alloc_fail", CTLFLAG_RD,
&sc->chain_alloc_fail, "chain allocation failures");
#endif //FreeBSD_version >= 900030
+
+ SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+ OID_AUTO, "spinup_wait_time", CTLFLAG_RD,
+ &sc->spinup_wait_time, DEFAULT_SPINUP_WAIT, "seconds to wait for "
+ "spinup after SATA ID error");
}
int
@@ -2096,7 +2098,7 @@ mpr_update_events(struct mpr_softc *sc, struct mpr_event_handle *handle,
(reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS)
error = ENXIO;
- if(reply)
+ if (reply)
mpr_print_event(sc, reply);
mpr_dprint(sc, MPR_TRACE, "%s finished error %d\n", __func__, error);
@@ -2163,8 +2165,8 @@ mpr_deregister_events(struct mpr_softc *sc, struct mpr_event_handle *handle)
* Add a chain element as the next SGE for the specified command.
* Reset cm_sge and cm_sgesize to indicate all the available space. Chains are
* only required for IEEE commands. Therefore there is no code for commands
- * that have the MPR_CM_FLAGS_SGE_SIMPLE flag set (and those commands shouldn't
- * be requesting chains).
+ * that have the MPR_CM_FLAGS_SGE_SIMPLE flag set (and those commands
+ * shouldn't be requesting chains).
*/
static int
mpr_add_chain(struct mpr_command *cm, int segsleft)
@@ -2246,9 +2248,9 @@ mpr_add_chain(struct mpr_command *cm, int segsleft)
/*
* Add one scatter-gather element to the scatter-gather list for a command.
- * Maintain cm_sglsize and cm_sge as the remaining size and pointer to the next
- * SGE to fill in, respectively. In Gen3, the MPI SGL does not have a chain,
- * so don't consider any chain additions.
+ * Maintain cm_sglsize and cm_sge as the remaining size and pointer to the
+ * next SGE to fill in, respectively. In Gen3, the MPI SGL does not have a
+ * chain, so don't consider any chain additions.
*/
int
mpr_push_sge(struct mpr_command *cm, MPI2_SGE_SIMPLE64 *sge, size_t len,
@@ -2660,7 +2662,7 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm)
}
}
- if(error) {
+ if (error) {
mpr_dprint(sc, MPR_FAULT, "Calling Reinit from %s\n", __func__);
rc = mpr_reinit(sc);
mpr_dprint(sc, MPR_FAULT, "Reinit %s\n", (rc == 0) ?
@@ -2717,9 +2719,12 @@ mpr_read_config_page(struct mpr_softc *sc, struct mpr_config_params *params)
cm->cm_data = params->buffer;
cm->cm_length = params->length;
- cm->cm_sge = &req->PageBufferSGE;
- cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
- cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
+ if (cm->cm_data != NULL) {
+ cm->cm_sge = &req->PageBufferSGE;
+ cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION);
+ cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN;
+ } else
+ cm->cm_sge = NULL;
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_complete_data = params;
@@ -2776,9 +2781,12 @@ mpr_config_complete(struct mpr_softc *sc, struct mpr_command *cm)
goto done;
}
params->status = reply->IOCStatus;
- if (params->hdr.Ext.ExtPageType != 0) {
+ if (params->hdr.Struct.PageType == MPI2_CONFIG_PAGETYPE_EXTENDED) {
params->hdr.Ext.ExtPageType = reply->ExtPageType;
params->hdr.Ext.ExtPageLength = reply->ExtPageLength;
+ params->hdr.Ext.PageType = reply->Header.PageType;
+ params->hdr.Ext.PageNumber = reply->Header.PageNumber;
+ params->hdr.Ext.PageVersion = reply->Header.PageVersion;
} else {
params->hdr.Struct.PageType = reply->Header.PageType;
params->hdr.Struct.PageNumber = reply->Header.PageNumber;
diff --git a/sys/dev/mpr/mpr_config.c b/sys/dev/mpr/mpr_config.c
index 125451608dee..c0ea3d5ffb08 100644
--- a/sys/dev/mpr/mpr_config.c
+++ b/sys/dev/mpr/mpr_config.c
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*/
#include <sys/cdefs.h>
diff --git a/sys/dev/mpr/mpr_ioctl.h b/sys/dev/mpr/mpr_ioctl.h
index 5ec482f311b0..aa1a4cbf7697 100644
--- a/sys/dev/mpr/mpr_ioctl.h
+++ b/sys/dev/mpr/mpr_ioctl.h
@@ -27,12 +27,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD userland interface
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD userland interface
*
* $FreeBSD$
*/
/*-
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,7 +57,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
diff --git a/sys/dev/mpr/mpr_mapping.c b/sys/dev/mpr/mpr_mapping.c
index 7f0fc00a9c52..110e6a3b943f 100644
--- a/sys/dev/mpr/mpr_mapping.c
+++ b/sys/dev/mpr/mpr_mapping.c
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*/
#include <sys/cdefs.h>
@@ -326,11 +327,13 @@ _mapping_get_high_missing_mt_idx(struct mpr_softc *sc)
{
u32 map_idx, high_idx = MPR_ENCTABLE_BAD_IDX;
u8 high_missing_count = 0;
- u32 start_idx, end_idx, start_idx_ir = 0, end_idx_ir;
+ u32 start_idx, end_idx, start_idx_ir, end_idx_ir;
struct dev_mapping_table *mt_entry;
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
start_idx = 0;
+ start_idx_ir = 0;
+ end_idx_ir = 0;
end_idx = sc->max_devices;
if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0)
start_idx = 1;
@@ -887,14 +890,14 @@ _mapping_get_dev_info(struct mpr_softc *sc,
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
Mpi2ConfigReply_t mpi_reply;
Mpi2SasDevicePage0_t sas_device_pg0;
- u8 entry, enc_idx, phy_idx;
+ u8 entry, enc_idx, phy_idx, sata_end_device;
u32 map_idx, index, device_info;
struct _map_phy_change *phy_change, *tmp_phy_change;
uint64_t sas_address;
struct enc_mapping_table *et_entry;
struct dev_mapping_table *mt_entry;
u8 add_code = MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED;
- int rc;
+ int rc = 1;
for (entry = 0; entry < topo_change->num_entries; entry++) {
phy_change = &topo_change->phy_details[entry];
@@ -908,41 +911,36 @@ _mapping_get_dev_info(struct mpr_softc *sc,
continue;
}
+ /*
+ * Always get SATA Identify information because this is used
+ * to determine if Start/Stop Unit should be sent to the drive
+ * when the system is shutdown.
+ */
device_info = le32toh(sas_device_pg0.DeviceInfo);
- if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
- MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
- if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) &&
- (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) {
- rc = mprsas_get_sas_address_for_sata_disk(sc,
- &sas_address, phy_change->dev_handle,
- device_info);
- if (rc) {
- printf("%s: failed to compute the "
- "hashed SAS Address for SATA "
- "device with handle 0x%04x\n",
- __func__, phy_change->dev_handle);
- sas_address =
- sas_device_pg0.SASAddress.High;
- sas_address = (sas_address << 32) |
- sas_device_pg0.SASAddress.Low;
- }
+ sas_address = sas_device_pg0.SASAddress.High;
+ sas_address = (sas_address << 32) |
+ sas_device_pg0.SASAddress.Low;
+ sata_end_device = 0;
+ if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) &&
+ (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) {
+ sata_end_device = 1;
+ rc = mprsas_get_sas_address_for_sata_disk(sc,
+ &sas_address, phy_change->dev_handle, device_info,
+ &phy_change->is_SATA_SSD);
+ if (rc) {
+ mpr_dprint(sc, MPR_ERROR, "%s: failed to get "
+ "disk type (SSD or HDD) and SAS Address "
+ "for SATA device with handle 0x%04x\n",
+ __func__, phy_change->dev_handle);
+ } else {
mpr_dprint(sc, MPR_INFO, "SAS Address for SATA "
"device = %jx\n", sas_address);
- } else {
- sas_address =
- sas_device_pg0.SASAddress.High;
- sas_address = (sas_address << 32) |
- sas_device_pg0.SASAddress.Low;
}
- } else {
- sas_address = sas_device_pg0.SASAddress.High;
- sas_address = (sas_address << 32) |
- sas_device_pg0.SASAddress.Low;
}
+
phy_change->physical_id = sas_address;
phy_change->slot = le16toh(sas_device_pg0.Slot);
- phy_change->device_info =
- le32toh(sas_device_pg0.DeviceInfo);
+ phy_change->device_info = le32toh(sas_device_pg0.DeviceInfo);
if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) ==
MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) {
@@ -950,10 +948,10 @@ _mapping_get_dev_info(struct mpr_softc *sc,
topo_change->enc_handle);
if (enc_idx == MPR_ENCTABLE_BAD_IDX) {
phy_change->is_processed = 1;
- printf("%s: failed to add the device with "
- "handle 0x%04x because the enclosure is "
- "not in the mapping table\n", __func__,
- phy_change->dev_handle);
+ mpr_dprint(sc, MPR_MAPPING, "%s: failed to add "
+ "the device with handle 0x%04x because the "
+ "enclosure is not in the mapping table\n",
+ __func__, phy_change->dev_handle);
continue;
}
if (!((phy_change->device_info &
diff --git a/sys/dev/mpr/mpr_mapping.h b/sys/dev/mpr/mpr_mapping.h
index 3250c424e2a4..c00a3b795122 100644
--- a/sys/dev/mpr/mpr_mapping.h
+++ b/sys/dev/mpr/mpr_mapping.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@@ -38,6 +39,7 @@
* @dev_handle: device handle for the device pointed by this entry
* @slot: slot ID
* @is_processed: Flag to indicate whether this entry is processed or not
+ * @is_SATA_SSD: 1 if this is a SATA device AND an SSD, 0 otherwise
*/
struct _map_phy_change {
uint64_t physical_id;
@@ -46,6 +48,8 @@ struct _map_phy_change {
uint16_t slot;
uint8_t reason;
uint8_t is_processed;
+ uint8_t is_SATA_SSD;
+ uint8_t reserved;
};
/**
@@ -66,6 +70,6 @@ struct _map_topology_change {
extern int
mprsas_get_sas_address_for_sata_disk(struct mpr_softc *ioc,
- u64 *sas_address, u16 handle, u32 device_info);
+ u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD);
#endif
diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c
index e19f33adceb4..7430eac03b3a 100644
--- a/sys/dev/mpr/mpr_pci.c
+++ b/sys/dev/mpr/mpr_pci.c
@@ -27,7 +27,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-/* PCI/PCI-X/PCIe bus interface for the LSI MPT2 controllers */
+/* PCI/PCI-X/PCIe bus interface for the Avago Tech (LSI) MPT3 controllers */
/* TODO Move headers to mprvar */
#include <sys/types.h>
@@ -99,17 +99,17 @@ struct mpr_ident {
const char *desc;
} mpr_identifiers[] = {
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004,
- 0xffff, 0xffff, 0, "LSI SAS3004" },
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3004" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008,
- 0xffff, 0xffff, 0, "LSI SAS3008" },
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3008" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1,
- 0xffff, 0xffff, 0, "LSI SAS3108_1" },
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_1" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2,
- 0xffff, 0xffff, 0, "LSI SAS3108_2" },
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_2" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5,
- 0xffff, 0xffff, 0, "LSI SAS3108_5" },
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_5" },
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
- 0xffff, 0xffff, 0, "LSI SAS3108_6" },
+ 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_6" },
{ 0, 0, 0, 0, 0, NULL }
};
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index 32c3a4633a1f..eac336068295 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,12 +24,15 @@
* 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.
+ *
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
+ *
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-/* Communications core for LSI MPT2 */
+/* Communications core for Avago Technologies (LSI) MPT3 */
/* TODO Move headers to mprvar */
#include <sys/types.h>
@@ -122,14 +126,10 @@ static void mprsas_scsiio_complete(struct mpr_softc *, struct mpr_command *);
static void mprsas_action_resetdev(struct mprsas_softc *, union ccb *);
static void mprsas_resetdev_complete(struct mpr_softc *,
struct mpr_command *);
-static int mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm,
+static int mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm,
struct mpr_command *cm);
-static int mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm,
- uint8_t type);
static void mprsas_async(void *callback_arg, uint32_t code,
struct cam_path *path, void *arg);
-static void mprsas_prepare_ssu(struct mpr_softc *sc, struct cam_path *path,
- struct ccb_getdev *cgd);
#if (__FreeBSD_version < 901503) || \
((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006))
static void mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
@@ -142,13 +142,12 @@ static void mprsas_portenable_complete(struct mpr_softc *sc,
struct mpr_command *cm);
#if __FreeBSD_version >= 900026
-static void
-mprsas_smpio_complete(struct mpr_softc *sc, struct mpr_command *cm);
+static void mprsas_smpio_complete(struct mpr_softc *sc,
+ struct mpr_command *cm);
static void mprsas_send_smpcmd(struct mprsas_softc *sassc,
- union ccb *ccb, uint64_t sasaddr);
-static void
-mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb);
-#endif
+ union ccb *ccb, uint64_t sasaddr);
+static void mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb);
+#endif //FreeBSD_version >= 900026
struct mprsas_target *
mprsas_find_target_by_handle(struct mprsas_softc *sassc, int start,
@@ -230,7 +229,7 @@ mprsas_startup_decrement(struct mprsas_softc *sassc)
}
}
-/* LSI's firmware requires us to stop sending commands when we're doing task
+/* The firmware requires us to stop sending commands when we're doing task
* management, so refcount the TMs and keep the simq frozen when any are in
* use.
*/
@@ -241,35 +240,31 @@ mprsas_alloc_tm(struct mpr_softc *sc)
MPR_FUNCTRACE(sc);
tm = mpr_alloc_high_priority_command(sc);
- if (tm != NULL) {
- if (sc->sassc->tm_count++ == 0) {
- mpr_dprint(sc, MPR_RECOVERY,
- "%s freezing simq\n", __func__);
- xpt_freeze_simq(sc->sassc->sim, 1);
- }
- mpr_dprint(sc, MPR_RECOVERY, "%s tm_count %u\n", __func__,
- sc->sassc->tm_count);
- }
return tm;
}
void
mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm)
{
- mpr_dprint(sc, MPR_TRACE, "%s", __func__);
+ MPR_FUNCTRACE(sc);
if (tm == NULL)
return;
- /* if there are no TMs in use, we can release the simq. We use our
- * own refcount so that it's easier for a diag reset to cleanup and
- * release the simq.
+ /*
+ * For TM's the devq is frozen for the device. Unfreeze it here and
+ * free the resources used for freezing the devq. Must clear the
+ * INRESET flag as well or scsi I/O will not work.
*/
- if (--sc->sassc->tm_count == 0) {
- mpr_dprint(sc, MPR_RECOVERY, "%s releasing simq\n", __func__);
- xpt_release_simq(sc->sassc->sim, 1);
+ if (tm->cm_targ != NULL) {
+ tm->cm_targ->flags &= ~MPRSAS_TARGET_INRESET;
+ }
+ if (tm->cm_ccb) {
+ mpr_dprint(sc, MPR_INFO, "Unfreezing devq for target ID %d\n",
+ tm->cm_targ->tid);
+ xpt_release_devq(tm->cm_ccb->ccb_h.path, 1, TRUE);
+ xpt_free_path(tm->cm_ccb->ccb_h.path);
+ xpt_free_ccb(tm->cm_ccb);
}
- mpr_dprint(sc, MPR_RECOVERY, "%s tm_count %u\n", __func__,
- sc->sassc->tm_count);
mpr_free_high_priority_command(sc, tm);
}
@@ -298,8 +293,8 @@ mprsas_rescan_target(struct mpr_softc *sc, struct mprsas_target *targ)
return;
}
- if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid,
- targetid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+ if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, targetid,
+ CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
mpr_dprint(sc, MPR_ERROR, "unable to create path for rescan\n");
xpt_free_ccb(ccb);
return;
@@ -473,11 +468,16 @@ mprsas_prepare_volume_remove(struct mprsas_softc *sassc, uint16_t handle)
MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
cm->cm_complete = mprsas_remove_volume;
cm->cm_complete_data = (void *)(uintptr_t)handle;
+
+ mpr_dprint(sc, MPR_INFO, "%s: Sending reset for target ID %d\n",
+ __func__, targ->tid);
+ mprsas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
+
mpr_map_command(sc, cm);
}
/*
- * The MPT2 firmware performs debounce on the link to avoid transient link
+ * The MPT3 firmware performs debounce on the link to avoid transient link
* errors and false removals. When it does decide that link has been lost
* and a device needs to go away, it expects that the host will perform a
* target reset and then an op remove. The reset has the side-effect of
@@ -532,6 +532,11 @@ mprsas_prepare_remove(struct mprsas_softc *sassc, uint16_t handle)
MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
cm->cm_complete = mprsas_remove_device;
cm->cm_complete_data = (void *)(uintptr_t)handle;
+
+ mpr_dprint(sc, MPR_INFO, "%s: Sending reset for target ID %d\n",
+ __func__, targ->tid);
+ mprsas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
+
mpr_map_command(sc, cm);
}
@@ -596,10 +601,10 @@ mprsas_remove_device(struct mpr_softc *sc, struct mpr_command *tm)
mpr_map_command(sc, tm);
- mpr_dprint(sc, MPR_XINFO, "clearing target %u handle 0x%04x\n",
+ mpr_dprint(sc, MPR_INFO, "clearing target %u handle 0x%04x\n",
targ->tid, handle);
if (targ->encl_level_valid) {
- mpr_dprint(sc, MPR_XINFO, "At enclosure level %d, slot %d, "
+ mpr_dprint(sc, MPR_INFO, "At enclosure level %d, slot %d, "
"connector name (%4s)\n", targ->encl_level, targ->encl_slot,
targ->connector_name);
}
@@ -608,7 +613,7 @@ mprsas_remove_device(struct mpr_softc *sc, struct mpr_command *tm)
mpr_dprint(sc, MPR_XINFO, "Completing missed command %p\n", tm);
ccb = tm->cm_complete_data;
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
mprsas_scsiio_complete(sc, tm);
}
}
@@ -726,7 +731,7 @@ mpr_attach_sas(struct mpr_softc *sc)
}
/*
- * XXX MaxTargets could change during a reinit. since we don't
+ * XXX MaxTargets could change during a reinit. Since we don't
* resize the targets[] array during such an event, cache the value
* of MaxTargets here so that we don't get into trouble later. This
* should move into the reinit logic.
@@ -782,7 +787,7 @@ mpr_attach_sas(struct mpr_softc *sc)
}
/*
- * Assume that discovery events will start right away. Freezing
+ * Assume that discovery events will start right away.
*
* Hold off boot until discovery is complete.
*/
@@ -790,9 +795,7 @@ mpr_attach_sas(struct mpr_softc *sc)
sc->sassc->startup_refcount = 0;
mprsas_startup_increment(sassc);
- callout_init(&sassc->discovery_callout, 1 /*mprafe*/);
-
- sassc->tm_count = 0;
+ callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
/*
* Register for async events so we can determine the EEDP
@@ -962,7 +965,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
sassc = cam_sim_softc(sim);
MPR_FUNCTRACE(sassc->sc);
- mpr_dprint(sassc->sc, MPR_TRACE, "%s func 0x%x\n", __func__,
+ mpr_dprint(sassc->sc, MPR_TRACE, "ccb func_code 0x%x\n",
ccb->ccb_h.func_code);
mtx_assert(&sassc->sc->mpr_mtx, MA_OWNED);
@@ -985,7 +988,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
cpi->max_lun = 255;
cpi->initiator_id = sassc->maxtargets - 1;
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(cpi->hba_vid, "LSILogic", HBA_IDLEN);
+ strncpy(cpi->hba_vid, "Avago Tech (LSI)", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(sim);
cpi->bus_id = cam_sim_bus(sim);
@@ -1005,7 +1008,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
*/
cpi->maxio = 256 * 1024;
#endif
- cpi->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
}
case XPT_GET_TRAN_SETTINGS:
@@ -1024,7 +1027,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
cts->ccb_h.target_id));
targ = &sassc->targets[cts->ccb_h.target_id];
if (targ->handle == 0x0) {
- cts->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
break;
}
@@ -1054,12 +1057,12 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
scsi->valid = CTS_SCSI_VALID_TQ;
scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
- cts->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
}
case XPT_CALC_GEOMETRY:
cam_calc_geometry(&ccb->ccg, /*extended*/1);
- ccb->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
case XPT_RESET_DEV:
mpr_dprint(sassc->sc, MPR_XINFO,
@@ -1071,7 +1074,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
case XPT_TERM_IO:
mpr_dprint(sassc->sc, MPR_XINFO,
"mprsas_action faking success for abort or reset\n");
- ccb->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
case XPT_SCSI_IO:
mprsas_action_scsiio(sassc, ccb);
@@ -1082,7 +1085,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
return;
#endif
default:
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+ mprsas_set_ccbstatus(ccb, CAM_FUNC_NOTAVAIL);
break;
}
xpt_done(ccb);
@@ -1102,7 +1105,7 @@ mprsas_announce_reset(struct mpr_softc *sc, uint32_t ac_code,
if (xpt_create_path(&path, NULL,
path_id, target_id, lun_id) != CAM_REQ_CMP) {
mpr_dprint(sc, MPR_ERROR, "unable to create path for reset "
- "notification\n");
+ "notification\n");
return;
}
@@ -1131,8 +1134,8 @@ mprsas_complete_all_commands(struct mpr_softc *sc)
if (cm->cm_complete != NULL) {
mprsas_log_command(cm, MPR_RECOVERY,
- "completing cm %p state %x ccb %p for diag reset\n",
- cm, cm->cm_state, cm->cm_ccb);
+ "completing cm %p state %x ccb %p for diag "
+ "reset\n", cm, cm->cm_state, cm->cm_ccb);
cm->cm_complete(sc, cm);
completed = 1;
}
@@ -1145,6 +1148,14 @@ mprsas_complete_all_commands(struct mpr_softc *sc)
completed = 1;
}
+ if (cm->cm_sc->io_cmds_active != 0) {
+ cm->cm_sc->io_cmds_active--;
+ } else {
+ mpr_dprint(cm->cm_sc, MPR_INFO, "Warning: "
+ "io_cmds_active is out of sync - resynching to "
+ "0\n");
+ }
+
if ((completed == 0) && (cm->cm_state != MPR_CM_STATE_FREE)) {
/* this should never happen, but if it does, log */
mprsas_log_command(cm, MPR_RECOVERY,
@@ -1180,9 +1191,8 @@ mprsas_handle_reinit(struct mpr_softc *sc)
/* complete and cleanup after all outstanding commands */
mprsas_complete_all_commands(sc);
- mpr_dprint(sc, MPR_INIT, "%s startup %u tm %u after command "
- "completion\n", __func__, sc->sassc->startup_refcount,
- sc->sassc->tm_count);
+ mpr_dprint(sc, MPR_INIT, "%s startup %u after command completion\n",
+ __func__, sc->sassc->startup_refcount);
/* zero all the target handles, since they may change after the
* reset, and we have to rediscover all the targets and use the new
@@ -1244,7 +1254,6 @@ mprsas_logical_unit_reset_complete(struct mpr_softc *sc,
"NULL reset reply for tm %p\n", tm);
if ((sc->mpr_flags & MPR_FLAGS_DIAGRESET) != 0) {
/* this completion was due to a reset, just cleanup */
- targ->flags &= ~MPRSAS_TARGET_INRESET;
targ->tm = NULL;
mprsas_free_tm(sc, tm);
}
@@ -1322,8 +1331,8 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm)
* task management commands don't have S/G lists.
*/
if ((tm->cm_flags & MPR_CM_FLAGS_ERROR_MASK) != 0) {
- mpr_dprint(sc, MPR_ERROR,"%s: cm_flags = %#x for target reset! "
- "This should not happen!\n", __func__, tm->cm_flags);
+ mpr_dprint(sc, MPR_ERROR, "%s: cm_flags = %#x for target "
+ "reset! This should not happen!\n", __func__, tm->cm_flags);
mprsas_free_tm(sc, tm);
return;
}
@@ -1333,7 +1342,6 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm)
"NULL reset reply for tm %p\n", tm);
if ((sc->mpr_flags & MPR_FLAGS_DIAGRESET) != 0) {
/* this completion was due to a reset, just cleanup */
- targ->flags &= ~MPRSAS_TARGET_INRESET;
targ->tm = NULL;
mprsas_free_tm(sc, tm);
}
@@ -1349,8 +1357,6 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm)
le16toh(reply->IOCStatus), le32toh(reply->ResponseCode),
le32toh(reply->TerminationCount));
- targ->flags &= ~MPRSAS_TARGET_INRESET;
-
if (targ->outstanding == 0) {
/* we've finished recovery for this target and all
* of its logical units.
@@ -1378,7 +1384,7 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm)
#define MPR_RESET_TIMEOUT 30
-static int
+int
mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type)
{
MPI2_SCSI_TASK_MANAGE_REQUEST *req;
@@ -1387,8 +1393,8 @@ mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type)
target = tm->cm_targ;
if (target->handle == 0) {
- mpr_dprint(sc, MPR_ERROR,"%s null devhandle for target_id %d\n",
- __func__, target->tid);
+ mpr_dprint(sc, MPR_ERROR, "%s null devhandle for target_id "
+ "%d\n", __func__, target->tid);
return -1;
}
@@ -1404,6 +1410,7 @@ mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type)
mprsas_log_command(tm, MPR_RECOVERY|MPR_INFO,
"sending logical unit reset\n");
tm->cm_complete = mprsas_logical_unit_reset_complete;
+ mprsas_prepare_for_tm(sc, tm, target, tm->cm_lun);
}
else if (type == MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
/*
@@ -1412,20 +1419,20 @@ mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type)
*/
req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
tm->cm_targ->target_resets++;
- tm->cm_targ->flags |= MPRSAS_TARGET_INRESET;
mprsas_log_command(tm, MPR_RECOVERY|MPR_INFO,
"sending target reset\n");
tm->cm_complete = mprsas_target_reset_complete;
+ mprsas_prepare_for_tm(sc, tm, target, CAM_LUN_WILDCARD);
}
else {
mpr_dprint(sc, MPR_ERROR, "unexpected reset type 0x%x\n", type);
return -1;
}
- mpr_dprint(sc, MPR_XINFO, "to target %u handle 0x%04x\n", target->tid,
+ mpr_dprint(sc, MPR_INFO, "to target %u handle 0x%04x\n", target->tid,
target->handle);
if (target->encl_level_valid) {
- mpr_dprint(sc, MPR_XINFO, "At enclosure level %d, slot %d, "
+ mpr_dprint(sc, MPR_INFO, "At enclosure level %d, slot %d, "
"connector name (%4s)\n", target->encl_level,
target->encl_slot, target->connector_name);
}
@@ -1441,8 +1448,7 @@ mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type)
err = mpr_map_command(sc, tm);
if (err)
mprsas_log_command(tm, MPR_RECOVERY,
- "error %d sending reset type %u\n",
- err, type);
+ "error %d sending reset type %u\n", err, type);
return err;
}
@@ -1573,6 +1579,10 @@ mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm,
targ->aborts++;
+ mpr_dprint(sc, MPR_INFO, "Sending reset from %s for target ID %d\n",
+ __func__, targ->tid);
+ mprsas_prepare_for_tm(sc, tm, targ, tm->cm_lun);
+
err = mpr_map_command(sc, tm);
if (err)
mprsas_log_command(tm, MPR_RECOVERY,
@@ -1581,7 +1591,6 @@ mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm,
return err;
}
-
static void
mprsas_scsiio_timeout(void *data)
{
@@ -1617,11 +1626,11 @@ mprsas_scsiio_timeout(void *data)
targ = cm->cm_targ;
targ->timeouts++;
- mprsas_log_command(cm, MPR_XINFO, "command timeout cm %p ccb %p "
+ mprsas_log_command(cm, MPR_ERROR, "command timeout cm %p ccb %p "
"target %u, handle(0x%04x)\n", cm, cm->cm_ccb, targ->tid,
targ->handle);
if (targ->encl_level_valid) {
- mpr_dprint(sc, MPR_XINFO, "At enclosure level %d, slot %d, "
+ mpr_dprint(sc, MPR_ERROR, "At enclosure level %d, slot %d, "
"connector name (%4s)\n", targ->encl_level, targ->encl_slot,
targ->connector_name);
}
@@ -1629,8 +1638,7 @@ mprsas_scsiio_timeout(void *data)
/* XXX first, check the firmware state, to see if it's still
* operational. if not, do a diag reset.
*/
-
- cm->cm_ccb->ccb_h.status = CAM_CMD_TIMEOUT;
+ mprsas_set_ccbstatus(cm->cm_ccb, CAM_CMD_TIMEOUT);
cm->cm_state = MPR_CM_STATE_TIMEDOUT;
TAILQ_INSERT_TAIL(&targ->timedout_commands, cm, cm_recovery);
@@ -1681,19 +1689,22 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
mtx_assert(&sc->mpr_mtx, MA_OWNED);
csio = &ccb->csio;
+ KASSERT(csio->ccb_h.target_id < sassc->maxtargets,
+ ("Target %d out of bounds in XPT_SCSI_IO\n",
+ csio->ccb_h.target_id));
targ = &sassc->targets[csio->ccb_h.target_id];
mpr_dprint(sc, MPR_TRACE, "ccb %p target flag %x\n", ccb, targ->flags);
if (targ->handle == 0x0) {
mpr_dprint(sc, MPR_ERROR, "%s NULL handle for target %u\n",
__func__, csio->ccb_h.target_id);
- csio->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
xpt_done(ccb);
return;
}
if (targ->flags & MPR_TARGET_FLAGS_RAID_COMPONENT) {
- mpr_dprint(sc, MPR_TRACE, "%s Raid component no SCSI IO "
+ mpr_dprint(sc, MPR_ERROR, "%s Raid component no SCSI IO "
"supported %u\n", __func__, csio->ccb_h.target_id);
- csio->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
xpt_done(ccb);
return;
}
@@ -1702,7 +1713,7 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
* Progress" and was actually aborted by the upper layer. Check for
* this here and complete the command without error.
*/
- if (ccb->ccb_h.status != CAM_REQ_INPROG) {
+ if (mprsas_get_ccbstatus(ccb) != CAM_REQ_INPROG) {
mpr_dprint(sc, MPR_TRACE, "%s Command is not in progress for "
"target %u\n", __func__, csio->ccb_h.target_id);
xpt_done(ccb);
@@ -1715,16 +1726,29 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
*/
if (targ->flags & MPRSAS_TARGET_INREMOVAL) {
if (targ->devinfo == 0)
- csio->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
else
- csio->ccb_h.status = CAM_SEL_TIMEOUT;
+ mprsas_set_ccbstatus(ccb, CAM_SEL_TIMEOUT);
xpt_done(ccb);
return;
}
if ((sc->mpr_flags & MPR_FLAGS_SHUTDOWN) != 0) {
- mpr_dprint(sc, MPR_TRACE, "%s shutting down\n", __func__);
- csio->ccb_h.status = CAM_DEV_NOT_THERE;
+ mpr_dprint(sc, MPR_INFO, "%s shutting down\n", __func__);
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
+ xpt_done(ccb);
+ return;
+ }
+
+ /*
+ * If target has a reset in progress, freeze the devq and return. The
+ * devq will be released when the TM reset is finished.
+ */
+ if (targ->flags & MPRSAS_TARGET_INRESET) {
+ ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN;
+ mpr_dprint(sc, MPR_INFO, "%s: Freezing devq for target ID %d\n",
+ __func__, targ->tid);
+ xpt_freeze_devq(ccb->ccb_h.path, 1);
xpt_done(ccb);
return;
}
@@ -1807,7 +1831,7 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
if (MPR_SET_LUN(req->LUN, csio->ccb_h.target_lun) != 0) {
mpr_free_command(sc, cm);
- ccb->ccb_h.status = CAM_LUN_INVALID;
+ mprsas_set_ccbstatus(ccb, CAM_LUN_INVALID);
xpt_done(ccb);
return;
}
@@ -1904,7 +1928,7 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
}
callout_reset_sbt(&cm->cm_callout, SBT_1MS * ccb->ccb_h.timeout, 0,
- mprsas_scsiio_timeout, cm, 0);
+ mprsas_scsiio_timeout, cm, 0);
targ->issued++;
targ->outstanding++;
@@ -2102,7 +2126,7 @@ mpr_sc_failed_io_info(struct mpr_softc *sc, struct ccb_scsiio *csio,
desc_scsi_state, scsi_state);
if (sc->mpr_debug & MPR_XINFO &&
- scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
+ scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
mpr_dprint(sc, MPR_XINFO, "-> Sense Buffer Data : Start :\n");
scsi_sense_print(csio);
mpr_dprint(sc, MPR_XINFO, "-> Sense Buffer Data : End :\n");
@@ -2126,6 +2150,8 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
u8 *TLR_bits, TLR_on;
int dir = 0, i;
u16 alloc_len;
+ struct mprsas_target *target;
+ target_id_t target_id;
MPR_FUNCTRACE(sc);
mpr_dprint(sc, MPR_TRACE,
@@ -2139,6 +2165,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
sassc = sc->sassc;
ccb = cm->cm_complete_data;
csio = &ccb->csio;
+ target_id = csio->ccb_h.target_id;
rep = (MPI2_SCSI_IO_REPLY *)cm->cm_reply;
/*
* XXX KDM if the chain allocation fails, does it matter if we do
@@ -2197,7 +2224,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
* because there can be no reply when we haven't actually
* gone out to the hardware.
*/
- ccb->ccb_h.status = CAM_REQUEUE_REQ;
+ mprsas_set_ccbstatus(ccb, CAM_REQUEUE_REQ);
/*
* Currently the only error included in the mask is
@@ -2214,7 +2241,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
xpt_freeze_simq(sassc->sim, 1);
sassc->flags |= MPRSAS_QUEUE_FROZEN;
mpr_dprint(sc, MPR_INFO, "Error sending command, "
- "freezing SIM queue\n");
+ "freezing SIM queue\n");
}
}
@@ -2224,7 +2251,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
* commands that were sent. All SSU commands should be completed before
* shutdown completes, meaning SSU_refcount will be 0 after SSU_started
* is TRUE.
- */
+ */
if (sc->SSU_started && (csio->cdb_io.cdb_bytes[0] == START_STOP_UNIT)) {
mpr_dprint(sc, MPR_INFO, "Decrementing SSU count.\n");
sc->SSU_refcount--;
@@ -2232,12 +2259,12 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
/* Take the fast path to completion */
if (cm->cm_reply == NULL) {
- if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
+ if (mprsas_get_ccbstatus(ccb) == CAM_REQ_INPROG) {
if ((sc->mpr_flags & MPR_FLAGS_DIAGRESET) != 0)
- ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
+ mprsas_set_ccbstatus(ccb, CAM_SCSI_BUS_RESET);
else {
- ccb->ccb_h.status = CAM_REQ_CMP;
- ccb->csio.scsi_status = SCSI_STATUS_OK;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
+ csio->scsi_status = SCSI_STATUS_OK;
}
if (sassc->flags & MPRSAS_QUEUE_FROZEN) {
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
@@ -2252,10 +2279,10 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
* CAM_REQ_CMP. The first is if MPR_CM_FLAGS_ERROR_MASK is
* set, the second is in the MPR_FLAGS_DIAGRESET above.
*/
- if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ if (mprsas_get_ccbstatus(ccb) != CAM_REQ_CMP) {
/*
* Freeze the dev queue so that commands are
- * executed in the correct order with after error
+ * executed in the correct order after error
* recovery.
*/
ccb->ccb_h.status |= CAM_DEV_QFRZN;
@@ -2285,7 +2312,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
/* Completion failed at the transport level. */
if (rep->SCSIState & (MPI2_SCSI_STATE_NO_SCSI_STATUS |
MPI2_SCSI_STATE_TERMINATED)) {
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
break;
}
@@ -2294,7 +2321,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
* recover the command.
*/
if (rep->SCSIState & MPI2_SCSI_STATE_AUTOSENSE_FAILED) {
- ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
+ mprsas_set_ccbstatus(ccb, CAM_AUTOSENSE_FAIL);
break;
}
@@ -2306,7 +2333,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
if ((rep->SCSIState & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) &&
((le32toh(rep->ResponseInfo) & MPI2_SCSI_RI_MASK_REASONCODE)
== MPR_SCSI_RI_INVALID_FRAME)) {
- sc->mapping_table[csio->ccb_h.target_id].TLR_bits =
+ sc->mapping_table[target_id].TLR_bits =
(u8)MPI2_SCSIIO_CONTROL_NO_TLR;
}
@@ -2318,16 +2345,16 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
*/
if ((rep->SCSIStatus == MPI2_SCSI_STATUS_COMMAND_TERMINATED) ||
(rep->SCSIStatus == MPI2_SCSI_STATUS_TASK_ABORTED)) {
- ccb->ccb_h.status = CAM_REQ_ABORTED;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_ABORTED);
break;
}
/* Handle normal status and sense */
csio->scsi_status = rep->SCSIStatus;
if (rep->SCSIStatus == MPI2_SCSI_STATUS_GOOD)
- ccb->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
else
- ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
+ mprsas_set_ccbstatus(ccb, CAM_SCSI_STATUS_ERROR);
if (rep->SCSIState & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
int sense_len, returned_sense_len;
@@ -2362,12 +2389,11 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
(csio->data_ptr != NULL) &&
((csio->data_ptr[0] & 0x1f) == T_SEQUENTIAL) &&
(sc->control_TLR) &&
- (sc->mapping_table[csio->ccb_h.target_id].device_info &
+ (sc->mapping_table[target_id].device_info &
MPI2_SAS_DEVICE_INFO_SSP_TARGET)) {
vpd_list = (struct scsi_vpd_supported_page_list *)
csio->data_ptr;
- TLR_bits = &sc->mapping_table[csio->ccb_h.target_id].
- TLR_bits;
+ TLR_bits = &sc->mapping_table[target_id].TLR_bits;
*TLR_bits = (u8)MPI2_SCSIIO_CONTROL_NO_TLR;
TLR_on = (u8)MPI2_SCSIIO_CONTROL_TLR_ON;
alloc_len = ((u16)csio->cdb_io.cdb_bytes[3] << 8) +
@@ -2380,6 +2406,24 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
}
}
}
+
+ /*
+ * If this is a SATA direct-access end device, mark it so that
+ * a SCSI StartStopUnit command will be sent to it when the
+ * driver is being shutdown.
+ */
+ if ((csio->cdb_io.cdb_bytes[0] == INQUIRY) &&
+ ((csio->data_ptr[0] & 0x1f) == T_DIRECT) &&
+ (sc->mapping_table[target_id].device_info &
+ MPI2_SAS_DEVICE_INFO_SATA_DEVICE) &&
+ ((sc->mapping_table[target_id].device_info &
+ MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
+ MPI2_SAS_DEVICE_INFO_END_DEVICE)) {
+ target = &sassc->targets[target_id];
+ target->supports_SSU = TRUE;
+ mpr_dprint(sc, MPR_XINFO, "Target %d supports SSU\n",
+ target_id);
+ }
break;
case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
@@ -2390,13 +2434,13 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
* failed.
*/
if (cm->cm_targ->devinfo == 0)
- ccb->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
else
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
break;
case MPI2_IOCSTATUS_INVALID_SGL:
mpr_print_scsiio_cmd(sc, cm);
- ccb->ccb_h.status = CAM_UNREC_HBA_ERROR;
+ mprsas_set_ccbstatus(ccb, CAM_UNREC_HBA_ERROR);
break;
case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
/*
@@ -2409,14 +2453,14 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
* on the console.
*/
if (cm->cm_state == MPR_CM_STATE_TIMEDOUT)
- ccb->ccb_h.status = CAM_CMD_TIMEOUT;
+ mprsas_set_ccbstatus(ccb, CAM_CMD_TIMEOUT);
else
- ccb->ccb_h.status = CAM_REQ_ABORTED;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_ABORTED);
break;
case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
/* resid is ignored for this condition */
csio->resid = 0;
- ccb->ccb_h.status = CAM_DATA_RUN_ERR;
+ mprsas_set_ccbstatus(ccb, CAM_DATA_RUN_ERR);
break;
case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
@@ -2425,7 +2469,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
* transient transport-related) errors, retry these without
* decrementing the retry count.
*/
- ccb->ccb_h.status = CAM_REQUEUE_REQ;
+ mprsas_set_ccbstatus(ccb, CAM_REQUEUE_REQ);
mprsas_log_command(cm, MPR_INFO,
"terminated ioc %x scsi %x state %x xfer %u\n",
le16toh(rep->IOCStatus), rep->SCSIStatus, rep->SCSIState,
@@ -2447,7 +2491,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
le16toh(rep->IOCStatus), rep->SCSIStatus, rep->SCSIState,
le32toh(rep->TransferCount));
csio->resid = cm->cm_length;
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
break;
}
@@ -2460,7 +2504,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm)
"queue\n");
}
- if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+ if (mprsas_get_ccbstatus(ccb) != CAM_REQ_CMP) {
ccb->ccb_h.status |= CAM_DEV_QFRZN;
xpt_freeze_devq(ccb->ccb_h.path, /*count*/ 1);
}
@@ -2487,16 +2531,16 @@ mprsas_smpio_complete(struct mpr_softc *sc, struct mpr_command *cm)
* in the standard request size.
*/
if ((cm->cm_flags & MPR_CM_FLAGS_ERROR_MASK) != 0) {
- mpr_dprint(sc, MPR_ERROR,"%s: cm_flags = %#x on SMP request!\n",
- __func__, cm->cm_flags);
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ mpr_dprint(sc, MPR_ERROR, "%s: cm_flags = %#x on SMP "
+ "request!\n", __func__, cm->cm_flags);
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
goto bailout;
}
rpl = (MPI2_SMP_PASSTHROUGH_REPLY *)cm->cm_reply;
if (rpl == NULL) {
mpr_dprint(sc, MPR_ERROR, "%s: NULL cm_reply!\n", __func__);
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
goto bailout;
}
@@ -2509,17 +2553,17 @@ mprsas_smpio_complete(struct mpr_softc *sc, struct mpr_command *cm)
rpl->SASStatus != MPI2_SASSTATUS_SUCCESS) {
mpr_dprint(sc, MPR_XINFO, "%s: IOCStatus %04x SASStatus %02x\n",
__func__, le16toh(rpl->IOCStatus), rpl->SASStatus);
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
goto bailout;
}
- mpr_dprint(sc, MPR_XINFO, "%s: SMP request to SAS address "
- "%#jx completed successfully\n", __func__, (uintmax_t)sasaddr);
+ mpr_dprint(sc, MPR_XINFO, "%s: SMP request to SAS address %#jx "
+ "completed successfully\n", __func__, (uintmax_t)sasaddr);
if (ccb->smpio.smp_response[2] == SMP_FR_ACCEPTED)
- ccb->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
else
- ccb->ccb_h.status = CAM_SMP_STATUS_ERROR;
+ mprsas_set_ccbstatus(ccb, CAM_SMP_STATUS_ERROR);
bailout:
/*
@@ -2558,7 +2602,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
*/
mpr_dprint(sc, MPR_ERROR, "%s: physical addresses not "
"supported\n", __func__);
- ccb->ccb_h.status = CAM_REQ_INVALID;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID);
xpt_done(ccb);
return;
case CAM_DATA_SG:
@@ -2571,7 +2615,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
mpr_dprint(sc, MPR_ERROR,
"%s: multiple request or response buffer segments "
"not supported for SMP\n", __func__);
- ccb->ccb_h.status = CAM_REQ_INVALID;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID);
xpt_done(ccb);
return;
}
@@ -2605,7 +2649,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
response = ccb->smpio.smp_response;
break;
default:
- ccb->ccb_h.status = CAM_REQ_INVALID;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID);
xpt_done(ccb);
return;
}
@@ -2614,9 +2658,9 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
* XXX We don't yet support physical addresses here.
*/
if (ccb->ccb_h.flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS)) {
- mpr_printf(sc, "%s: physical addresses not supported\n",
- __func__);
- ccb->ccb_h.status = CAM_REQ_INVALID;
+ mpr_dprint(sc, MPR_ERROR, "%s: physical addresses not "
+ "supported\n", __func__);
+ mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID);
xpt_done(ccb);
return;
}
@@ -2635,7 +2679,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
mpr_dprint(sc, MPR_ERROR, "%s: multiple request or "
"response buffer segments not supported for SMP\n",
__func__);
- ccb->ccb_h.status = CAM_REQ_INVALID;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID);
xpt_done(ccb);
return;
}
@@ -2673,7 +2717,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
if (cm == NULL) {
mpr_dprint(sc, MPR_ERROR,
"%s: cannot allocate command\n", __func__);
- ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+ mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL);
xpt_done(ccb);
return;
}
@@ -2760,7 +2804,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
bailout_error:
mpr_free_command(sc, cm);
- ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+ mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL);
xpt_done(ccb);
return;
}
@@ -2783,7 +2827,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb)
if (targ->handle == 0x0) {
mpr_dprint(sc, MPR_ERROR, "%s: target %d does not exist!\n",
__func__, ccb->ccb_h.target_id);
- ccb->ccb_h.status = CAM_SEL_TIMEOUT;
+ mprsas_set_ccbstatus(ccb, CAM_SEL_TIMEOUT);
xpt_done(ccb);
return;
}
@@ -2831,7 +2875,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb)
if (targ->parent_handle == 0x0) {
mpr_dprint(sc, MPR_ERROR, "%s: handle %d does not have "
"a valid parent handle!\n", __func__, targ->handle);
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
goto bailout;
}
#ifdef OLD_MPR_PROBE
@@ -2841,7 +2885,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb)
if (parent_target == NULL) {
mpr_dprint(sc, MPR_ERROR, "%s: handle %d does not have "
"a valid parent target!\n", __func__, targ->handle);
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
goto bailout;
}
@@ -2850,9 +2894,8 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb)
mpr_dprint(sc, MPR_ERROR, "%s: handle %d parent %d "
"does not have an SMP target!\n", __func__,
targ->handle, parent_target->handle);
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
goto bailout;
-
}
sasaddr = parent_target->sasaddr;
@@ -2862,7 +2905,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb)
mpr_dprint(sc, MPR_ERROR, "%s: handle %d parent %d "
"does not have an SMP target!\n", __func__,
targ->handle, targ->parent_handle);
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
goto bailout;
}
@@ -2870,7 +2913,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb)
mpr_dprint(sc, MPR_ERROR, "%s: handle %d parent handle "
"%d does not have a valid SAS address!\n", __func__,
targ->handle, targ->parent_handle);
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
goto bailout;
}
@@ -2882,7 +2925,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb)
if (sasaddr == 0) {
mpr_dprint(sc, MPR_INFO, "%s: unable to find SAS address for "
"handle %d\n", __func__, targ->handle);
- ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+ mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE);
goto bailout;
}
mprsas_send_smpcmd(sassc, ccb, sasaddr);
@@ -2914,7 +2957,7 @@ mprsas_action_resetdev(struct mprsas_softc *sassc, union ccb *ccb)
if (tm == NULL) {
mpr_dprint(sc, MPR_ERROR,
"command alloc failure in mprsas_action_resetdev\n");
- ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+ mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL);
xpt_done(ccb);
return;
}
@@ -2933,7 +2976,12 @@ mprsas_action_resetdev(struct mprsas_softc *sassc, union ccb *ccb)
MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
tm->cm_complete = mprsas_resetdev_complete;
tm->cm_complete_data = ccb;
+
+ mpr_dprint(sc, MPR_INFO, "%s: Sending reset for target ID %d\n",
+ __func__, targ->tid);
tm->cm_targ = targ;
+ targ->flags |= MPRSAS_TARGET_INRESET;
+
mpr_map_command(sc, tm);
}
@@ -2962,7 +3010,7 @@ mprsas_resetdev_complete(struct mpr_softc *sc, struct mpr_command *tm)
mpr_dprint(sc, MPR_ERROR, "%s: cm_flags = %#x for reset of "
"handle %#04x! This should not happen!\n", __func__,
tm->cm_flags, req->DevHandle);
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
goto bailout;
}
@@ -2971,12 +3019,12 @@ mprsas_resetdev_complete(struct mpr_softc *sc, struct mpr_command *tm)
le16toh(resp->IOCStatus), le32toh(resp->ResponseCode));
if (le32toh(resp->ResponseCode) == MPI2_SCSITASKMGMT_RSP_TM_COMPLETE) {
- ccb->ccb_h.status = CAM_REQ_CMP;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
mprsas_announce_reset(sc, AC_SENT_BDR, tm->cm_targ->tid,
CAM_LUN_WILDCARD);
}
else
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR);
bailout:
@@ -2995,7 +3043,8 @@ mprsas_poll(struct cam_sim *sim)
/* frequent debug messages during a panic just slow
* everything down too much.
*/
- mpr_printf(sassc->sc, "%s clearing MPR_TRACE\n", __func__);
+ mpr_dprint(sassc->sc, MPR_XINFO, "%s clearing MPR_TRACE\n",
+ __func__);
sassc->sc->mpr_debug &= ~MPR_TRACE;
}
@@ -3094,7 +3143,7 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path,
if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
- if (((cdai.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
+ if ((mprsas_get_ccbstatus((union ccb *)&cdai) == CAM_REQ_CMP)
&& (rcap_buf.prot & SRC16_PROT_EN)) {
lun->eedp_formatted = TRUE;
lun->eedp_block_size = scsi_4btoul(rcap_buf.length);
@@ -3121,8 +3170,6 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path,
#endif
cgd = arg;
- mprsas_prepare_ssu(sc, path, cgd);
-
#if (__FreeBSD_version < 901503) || \
((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006))
mprsas_check_eedp(sc, path, cgd);
@@ -3134,64 +3181,6 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path,
}
}
-static void
-mprsas_prepare_ssu(struct mpr_softc *sc, struct cam_path *path,
- struct ccb_getdev *cgd)
-{
- struct mprsas_softc *sassc = sc->sassc;
- path_id_t pathid;
- target_id_t targetid;
- lun_id_t lunid;
- struct mprsas_target *target;
- struct mprsas_lun *lun;
- uint8_t found_lun;
-
- sassc = sc->sassc;
- pathid = cam_sim_path(sassc->sim);
- targetid = xpt_path_target_id(path);
- lunid = xpt_path_lun_id(path);
-
- KASSERT(targetid < sassc->maxtargets,
- ("Target %d out of bounds in mprsas_prepare_ssu\n", targetid));
- target = &sassc->targets[targetid];
- if (target->handle == 0x0)
- return;
-
- /*
- * If LUN is already in list, don't create a new one.
- */
- found_lun = FALSE;
- SLIST_FOREACH(lun, &target->luns, lun_link) {
- if (lun->lun_id == lunid) {
- found_lun = TRUE;
- break;
- }
- }
- if (!found_lun) {
- lun = malloc(sizeof(struct mprsas_lun), M_MPR,
- M_NOWAIT | M_ZERO);
- if (lun == NULL) {
- mpr_dprint(sc, MPR_ERROR, "Unable to alloc LUN for "
- "preparing SSU.\n");
- return;
- }
- lun->lun_id = lunid;
- SLIST_INSERT_HEAD(&target->luns, lun, lun_link);
- }
-
- /*
- * If this is a SATA direct-access end device, mark it so that a SCSI
- * StartStopUnit command will be sent to it when the driver is being
- * shutdown.
- */
- if (((cgd->inq_data.device & 0x1F) == T_DIRECT) &&
- (target->devinfo & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) &&
- ((target->devinfo & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) ==
- MPI2_SAS_DEVICE_INFO_END_DEVICE)) {
- lun->stop_at_shutdown = TRUE;
- }
-}
-
#if (__FreeBSD_version < 901503) || \
((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006))
static void
@@ -3212,7 +3201,6 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
uint8_t found_lun;
char path_str[64];
- sassc = sc->sassc;
pathid = cam_sim_path(sassc->sim);
targetid = xpt_path_target_id(path);
lunid = xpt_path_lun_id(path);
@@ -3288,7 +3276,7 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
rcap_buf = malloc(sizeof(struct scsi_read_capacity_eedp), M_MPR,
M_NOWAIT | M_ZERO);
if (rcap_buf == NULL) {
- mpr_dprint(sc, MPR_FAULT, "Unable to alloc read capacity "
+ mpr_dprint(sc, MPR_ERROR, "Unable to alloc read capacity "
"buffer for EEDP support.\n");
xpt_free_path(ccb->ccb_h.path);
xpt_free_ccb(ccb);
@@ -3341,7 +3329,7 @@ mprsas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
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;
/*
@@ -3359,21 +3347,21 @@ mprsas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
/*
* Got the LUN in the target's LUN list. Fill it in with EEDP
- * info. If the READ CAP 16 command had some SCSI error (common
+ * info. If the READ CAP 16 command had some SCSI error (common
* if command is not supported), mark the lun as not supporting
* EEDP and set the block size to 0.
*/
- if (((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
- || (done_ccb->csio.scsi_status != SCSI_STATUS_OK)) {
+ if ((mprsas_get_ccbstatus(done_ccb) != CAM_REQ_CMP) ||
+ (done_ccb->csio.scsi_status != SCSI_STATUS_OK)) {
lun->eedp_formatted = FALSE;
lun->eedp_block_size = 0;
break;
}
if (rcap_buf->protect & 0x01) {
- mpr_dprint(sassc->sc, MPR_INFO, "LUN %d for "
- "target ID %d is formatted for EEDP "
- "support.\n", done_ccb->ccb_h.target_lun,
+ mpr_dprint(sassc->sc, MPR_INFO, "LUN %d for target ID "
+ "%d is formatted for EEDP support.\n",
+ done_ccb->ccb_h.target_lun,
done_ccb->ccb_h.target_id);
lun->eedp_formatted = TRUE;
lun->eedp_block_size = scsi_4btoul(rcap_buf->length);
@@ -3389,6 +3377,34 @@ mprsas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
#endif /* (__FreeBSD_version < 901503) || \
((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006)) */
+void
+mprsas_prepare_for_tm(struct mpr_softc *sc, struct mpr_command *tm,
+ struct mprsas_target *target, lun_id_t lun_id)
+{
+ union ccb *ccb;
+ path_id_t path_id;
+
+ /*
+ * Set the INRESET flag for this target so that no I/O will be sent to
+ * the target until the reset has completed. If an I/O request does
+ * happen, the devq will be frozen. The CCB holds the path which is
+ * used to release the devq. The devq is released and the CCB is freed
+ * when the TM completes.
+ */
+ ccb = xpt_alloc_ccb_nowait();
+ if (ccb) {
+ path_id = cam_sim_path(sc->sassc->sim);
+ if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, path_id,
+ target->tid, lun_id) != CAM_REQ_CMP) {
+ xpt_free_ccb(ccb);
+ } else {
+ tm->cm_ccb = ccb;
+ tm->cm_targ = target;
+ target->flags |= MPRSAS_TARGET_INRESET;
+ }
+ }
+}
+
int
mprsas_startup(struct mpr_softc *sc)
{
@@ -3489,3 +3505,33 @@ mprsas_check_id(struct mprsas_softc *sassc, int id)
return (0);
}
+
+void
+mprsas_realloc_targets(struct mpr_softc *sc, int maxtargets)
+{
+ struct mprsas_softc *sassc;
+ struct mprsas_lun *lun, *lun_tmp;
+ struct mprsas_target *targ;
+ int i;
+
+ sassc = sc->sassc;
+ /*
+ * The number of targets is based on IOC Facts, so free all of
+ * the allocated LUNs for each target and then the target buffer
+ * itself.
+ */
+ for (i=0; i< maxtargets; i++) {
+ targ = &sassc->targets[i];
+ SLIST_FOREACH_SAFE(lun, &targ->luns, lun_link, lun_tmp) {
+ free(lun, M_MPR);
+ }
+ }
+ free(sassc->targets, M_MPR);
+
+ sassc->targets = malloc(sizeof(struct mprsas_target) * maxtargets,
+ M_MPR, M_WAITOK|M_ZERO);
+ if (!sassc->targets) {
+ panic("%s failed to alloc targets with error %d\n",
+ __func__, ENOMEM);
+ }
+}
diff --git a/sys/dev/mpr/mpr_sas.h b/sys/dev/mpr/mpr_sas.h
index 9d3116af29d0..ebeed300c9fb 100644
--- a/sys/dev/mpr/mpr_sas.h
+++ b/sys/dev/mpr/mpr_sas.h
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@@ -35,7 +36,6 @@ struct mprsas_lun {
lun_id_t lun_id;
uint8_t eedp_formatted;
uint32_t eedp_block_size;
- uint8_t stop_at_shutdown;
};
struct mprsas_target {
@@ -55,11 +55,10 @@ struct mprsas_target {
#define MPRSAS_TARGET_INREMOVAL (1 << 3)
#define MPR_TARGET_FLAGS_RAID_COMPONENT (1 << 4)
#define MPR_TARGET_FLAGS_VOLUME (1 << 5)
+#define MPR_TARGET_IS_SATA_SSD (1 << 6)
#define MPRSAS_TARGET_INRECOVERY (MPRSAS_TARGET_INABORT | \
MPRSAS_TARGET_INRESET | MPRSAS_TARGET_INCHIPRESET)
-#define MPRSAS_TARGET_ADD (1 << 29)
-#define MPRSAS_TARGET_REMOVE (1 << 30)
uint16_t tid;
SLIST_HEAD(, mprsas_lun) luns;
TAILQ_HEAD(, mpr_command) commands;
@@ -82,6 +81,8 @@ struct mprsas_target {
unsigned int logical_unit_resets;
unsigned int target_resets;
uint8_t scsi_req_desc_type;
+ uint8_t stop_at_shutdown;
+ uint8_t supports_SSU;
};
struct mprsas_softc {
@@ -92,7 +93,6 @@ struct mprsas_softc {
#define MPRSAS_DISCOVERY_TIMEOUT_PENDING (1 << 2)
#define MPRSAS_QUEUE_FROZEN (1 << 3)
#define MPRSAS_SHUTDOWN (1 << 4)
-#define MPRSAS_SCANTHREAD (1 << 5)
u_int maxtargets;
struct mprsas_target *targets;
struct cam_devq *devq;
@@ -103,7 +103,6 @@ struct mprsas_softc {
struct mpr_event_handle *mprsas_eh;
u_int startup_refcount;
- u_int tm_count;
struct proc *sysctl_proc;
struct taskqueue *ev_tq;
@@ -150,6 +149,19 @@ mprsas_set_lun(uint8_t *lun, u_int ccblun)
return (0);
}
+static __inline void
+mprsas_set_ccbstatus(union ccb *ccb, int status)
+{
+ ccb->ccb_h.status &= ~CAM_STATUS_MASK;
+ ccb->ccb_h.status |= status;
+}
+
+static __inline int
+mprsas_get_ccbstatus(union ccb *ccb)
+{
+ return (ccb->ccb_h.status & CAM_STATUS_MASK);
+}
+
#define MPR_SET_SINGLE_LUN(req, lun) \
do { \
bzero((req)->LUN, 8); \
@@ -158,11 +170,10 @@ do { \
void mprsas_rescan_target(struct mpr_softc *sc, struct mprsas_target *targ);
void mprsas_discovery_end(struct mprsas_softc *sassc);
+void mprsas_prepare_for_tm(struct mpr_softc *sc, struct mpr_command *tm,
+ struct mprsas_target *target, lun_id_t lun_id);
void mprsas_startup_increment(struct mprsas_softc *sassc);
void mprsas_startup_decrement(struct mprsas_softc *sassc);
-void mprsas_release_simq_reinit(struct mprsas_softc *sassc);
-struct mpr_command * mprsas_alloc_tm(struct mpr_softc *sc);
-void mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm);
void mprsas_firmware_event_work(void *arg, int pending);
int mprsas_check_id(struct mprsas_softc *sassc, int id);
diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c
index 32e9b3a07804..7d6ef7070f7d 100644
--- a/sys/dev/mpr/mpr_sas_lsi.c
+++ b/sys/dev/mpr/mpr_sas_lsi.c
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -23,13 +24,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-/* Communications core for LSI MPT2 */
+/* Communications core for LSI MPT3 */
/* TODO Move headers to mprvar */
#include <sys/types.h>
@@ -105,7 +106,9 @@ struct _ata_identify_device_data {
u16 serial_number[10]; /* 10-19 */
u16 reserved2[7]; /* 20-26 */
u16 model_number[20]; /* 27-46*/
- u16 reserved3[209]; /* 47-255*/
+ u16 reserved3[170]; /* 47-216 */
+ u16 rotational_speed; /* 217 */
+ u16 reserved4[38]; /* 218-255 */
};
static u32 event_count;
static void mprsas_fw_work(struct mpr_softc *sc,
@@ -116,8 +119,9 @@ static int mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate);
static int mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz,
u32 devinfo);
+static void mprsas_ata_id_timeout(void *data);
int mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc,
- u64 *sas_address, u16 handle, u32 device_info);
+ u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD);
static int mprsas_volume_add(struct mpr_softc *sc,
u16 handle);
static void mprsas_SSU_to_SATA_devices(struct mpr_softc *sc);
@@ -325,7 +329,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
return;
}
- mpr_dprint(sc, MPR_INFO, "Sending FP action "
+ mpr_dprint(sc, MPR_EVENT, "Sending FP action "
"from "
"MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST "
":\n");
@@ -350,9 +354,9 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
if (reply && (le16toh(reply->IOCStatus) &
MPI2_IOCSTATUS_MASK) !=
MPI2_IOCSTATUS_SUCCESS) {
- mpr_dprint(sc, MPR_INFO, "%s: error "
- "sending RaidActionPage; iocstatus "
- "= 0x%x\n", __func__,
+ mpr_dprint(sc, MPR_ERROR, "%s: error "
+ "sending RaidActionPage; "
+ "iocstatus = 0x%x\n", __func__,
le16toh(reply->IOCStatus));
}
@@ -360,7 +364,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
mpr_free_command(sc, cm);
}
skip_fp_send:
- mpr_dprint(sc, MPR_INFO, "Received "
+ mpr_dprint(sc, MPR_EVENT, "Received "
"MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST Reason "
"code %x:\n", element->ReasonCode);
switch (element->ReasonCode) {
@@ -421,7 +425,6 @@ skip_fp_send:
break;
targ->flags |= MPR_TARGET_FLAGS_RAID_COMPONENT;
mprsas_rescan_target(sc, targ);
-
break;
case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
/*
@@ -678,14 +681,13 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
struct mprsas_target *targ;
Mpi2ConfigReply_t mpi_reply;
Mpi2SasDevicePage0_t config_page;
- uint64_t sas_address, sata_sas_address;
- uint64_t parent_sas_address = 0;
- u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
+ uint64_t sas_address, parent_sas_address = 0;
u32 device_info, parent_devinfo = 0;
unsigned int id;
- int ret;
- int error = 0;
+ int ret = 1, error = 0, i;
struct mprsas_lun *lun;
+ u8 is_SATA_SSD = 0;
+ struct mpr_command *cm;
sassc = sc->sassc;
mprsas_startup_increment(sassc);
@@ -717,26 +719,29 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
}
/* TODO Check proper endianess */
sas_address = config_page.SASAddress.High;
- sas_address = (sas_address << 32) |
- config_page.SASAddress.Low;
-
- if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE)
- == MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) {
- if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) {
- ret = mprsas_get_sas_address_for_sata_disk(sc,
- &sata_sas_address, handle, device_info);
- if (!ret)
- id = mpr_mapping_get_sas_id(sc,
- sata_sas_address, handle);
- else
- id = mpr_mapping_get_sas_id(sc,
- sas_address, handle);
- } else
- id = mpr_mapping_get_sas_id(sc, sas_address,
- handle);
- } else
- id = mpr_mapping_get_sas_id(sc, sas_address, handle);
+ sas_address = (sas_address << 32) | config_page.SASAddress.Low;
+ mpr_dprint(sc, MPR_INFO, "SAS Address from SAS device page0 = %jx\n",
+ sas_address);
+
+ /*
+ * Always get SATA Identify information because this is used to
+ * determine if Start/Stop Unit should be sent to the drive when the
+ * system is shutdown.
+ */
+ if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) {
+ ret = mprsas_get_sas_address_for_sata_disk(sc, &sas_address,
+ handle, device_info, &is_SATA_SSD);
+ if (ret) {
+ mpr_dprint(sc, MPR_ERROR, "%s: failed to get disk type "
+ "(SSD or HDD) for SATA device with handle 0x%04x\n",
+ __func__, handle);
+ } else {
+ mpr_dprint(sc, MPR_INFO, "SAS Address from SATA "
+ "device = %jx\n", sas_address);
+ }
+ }
+ id = mpr_mapping_get_sas_id(sc, sas_address, handle);
if (id == MPR_MAP_BAD_ID) {
printf("failure at %s:%d/%s()! Could not get ID for device "
"with handle 0x%04x\n", __FILE__, __LINE__, __func__,
@@ -750,7 +755,7 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
error = ENXIO;
goto out;
}
-
+
mpr_dprint(sc, MPR_MAPPING, "SAS Address from SAS device page0 = %jx\n",
sas_address);
targ = &sassc->targets[id];
@@ -773,6 +778,9 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
targ->tid = id;
targ->linkrate = (linkrate>>4);
targ->flags = 0;
+ if (is_SATA_SSD) {
+ targ->flags = MPR_TARGET_IS_SATA_SSD;
+ }
if (le16toh(config_page.Flags) &
MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) {
targ->scsi_req_desc_type =
@@ -792,12 +800,12 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
SLIST_INIT(&targ->luns);
mpr_describe_devinfo(targ->devinfo, devstring, 80);
- mpr_dprint(sc, (MPR_XINFO|MPR_MAPPING), "Found device <%s> <%s> "
+ mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "Found device <%s> <%s> "
"handle<0x%04x> enclosureHandle<0x%04x> slot %d\n", devstring,
mpr_describe_table(mpr_linkrate_names, targ->linkrate),
targ->handle, targ->encl_handle, targ->encl_slot);
if (targ->encl_level_valid) {
- mpr_dprint(sc, (MPR_XINFO|MPR_MAPPING), "At enclosure level %d "
+ mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "At enclosure level %d "
"and connector name (%4s)\n", targ->encl_level,
targ->connector_name);
}
@@ -807,15 +815,57 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){
#endif
mprsas_rescan_target(sc, targ);
mpr_dprint(sc, MPR_MAPPING, "Target id 0x%x added\n", targ->tid);
+
+ /*
+ * Check all commands to see if the SATA_ID_TIMEOUT flag has been set.
+ * If so, send a Target Reset TM to the target that was just created.
+ * An Abort Task TM should be used instead of a Target Reset, but that
+ * would be much more difficult because targets have not been fully
+ * discovered yet, and LUN's haven't been setup. So, just reset the
+ * target instead of the LUN.
+ */
+ for (i = 1; i < sc->num_reqs; i++) {
+ cm = &sc->commands[i];
+ if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
+ targ->timeouts++;
+ cm->cm_state = MPR_CM_STATE_TIMEDOUT;
+
+ if ((targ->tm = mprsas_alloc_tm(sc)) != NULL) {
+ mpr_dprint(sc, MPR_INFO, "%s: sending Target "
+ "Reset for stuck SATA identify command "
+ "(cm = %p)\n", __func__, cm);
+ targ->tm->cm_targ = targ;
+ mprsas_send_reset(sc, targ->tm,
+ MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
+ } else {
+ mpr_dprint(sc, MPR_ERROR, "Failed to allocate "
+ "tm for Target Reset after SATA ID "
+ "command timed out (cm %p)\n", cm);
+ }
+ /*
+ * No need to check for more since the target is
+ * already being reset.
+ */
+ break;
+ }
+ }
out:
+ /*
+ * Free the commands that may not have been freed from the SATA ID call
+ */
+ for (i = 1; i < sc->num_reqs; i++) {
+ cm = &sc->commands[i];
+ if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) {
+ mpr_free_command(sc, cm);
+ }
+ }
mprsas_startup_decrement(sassc);
return (error);
-
}
int
mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc,
- u64 *sas_address, u16 handle, u32 device_info)
+ u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD)
{
Mpi2SataPassthroughReply_t mpi_reply;
int i, rc, try_count;
@@ -835,7 +885,16 @@ mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc,
ioc_status = le16toh(mpi_reply.IOCStatus)
& MPI2_IOCSTATUS_MASK;
sas_status = mpi_reply.SASStatus;
- } while ((rc == -EAGAIN || ioc_status || sas_status) &&
+ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+ if (sc->spinup_wait_time > 0) {
+ mpr_dprint(sc, MPR_INFO, "Sleeping %d seconds "
+ "after SATA ID error to wait for spinup\n",
+ sc->spinup_wait_time);
+ msleep(&sc->msleep_fake_chan, &sc->mpr_mtx, 0,
+ "mprid", sc->spinup_wait_time * hz);
+ }
+ }
+ } while (((rc && (rc != EWOULDBLOCK)) || ioc_status || sas_status) &&
(try_count < 5));
if (rc == 0 && !ioc_status && !sas_status) {
@@ -884,6 +943,10 @@ mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc,
(u64)hash_address.wwid[3] << 32 | (u64)hash_address.wwid[4] << 24 |
(u64)hash_address.wwid[5] << 16 | (u64)hash_address.wwid[6] << 8 |
(u64)hash_address.wwid[7];
+ if (ata_identify.rotational_speed == 1) {
+ *is_SATA_SSD = 1;
+ }
+
return 0;
}
@@ -923,14 +986,29 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
cm->cm_data = buffer;
cm->cm_length = htole32(sz);
+
+ /*
+ * Start a timeout counter specifically for the SATA ID command. This
+ * is used to fix a problem where the FW does not send a reply sometimes
+ * when a bad disk is in the topology. So, this is used to timeout the
+ * command so that processing can continue normally.
+ */
+ mpr_dprint(sc, MPR_XINFO, "%s start timeout counter for SATA ID "
+ "command\n", __func__);
+ callout_reset(&cm->cm_callout, MPR_ATA_ID_TIMEOUT * hz,
+ mprsas_ata_id_timeout, cm);
error = mpr_wait_command(sc, cm, 60, CAN_SLEEP);
+ mpr_dprint(sc, MPR_XINFO, "%s stop timeout counter for SATA ID "
+ "command\n", __func__);
+ callout_stop(&cm->cm_callout);
+
reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply;
if (error || (reply == NULL)) {
/* FIXME */
/*
* If the request returns an error then we need to do a diag
* reset
- */
+ */
printf("%s: request for page completed with error %d",
__func__, error);
error = ENXIO;
@@ -946,11 +1024,66 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
goto out;
}
out:
- mpr_free_command(sc, cm);
- free(buffer, M_MPR);
+ /*
+ * If the SATA_ID_TIMEOUT flag has been set for this command, don't free
+ * it. The command will be freed after sending a target reset TM. If
+ * the command did timeout, use EWOULDBLOCK.
+ */
+ if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0)
+ mpr_free_command(sc, cm);
+ else if (error == 0)
+ error = EWOULDBLOCK;
+ free(buffer, M_MPR);
return (error);
}
+static void
+mprsas_ata_id_timeout(void *data)
+{
+ struct mpr_softc *sc;
+ struct mpr_command *cm;
+
+ cm = (struct mpr_command *)data;
+ sc = cm->cm_sc;
+ mtx_assert(&sc->mpr_mtx, MA_OWNED);
+
+ mpr_dprint(sc, MPR_INFO, "%s checking ATA ID command %p sc %p\n",
+ __func__, cm, sc);
+ if ((callout_pending(&cm->cm_callout)) ||
+ (!callout_active(&cm->cm_callout))) {
+ mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed "
+ "out\n", __func__);
+ return;
+ }
+ callout_deactivate(&cm->cm_callout);
+
+ /*
+ * Run the interrupt handler to make sure it's not pending. This
+ * isn't perfect because the command could have already completed
+ * and been re-used, though this is unlikely.
+ */
+ mpr_intr_locked(sc);
+ if (cm->cm_state == MPR_CM_STATE_FREE) {
+ mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed "
+ "out\n", __func__);
+ return;
+ }
+
+ mpr_dprint(sc, MPR_INFO, "ATA ID command timeout cm %p\n", cm);
+
+ /*
+ * Send wakeup() to the sleeping thread that issued this ATA ID
+ * command. wakeup() will cause msleep to return a 0 (not EWOULDBLOCK),
+ * and this will keep reinit() from being called. This way, an Abort
+ * Task TM can be issued so that the timed out command can be cleared.
+ * The Abort Task cannot be sent from here because the driver has not
+ * completed setting up targets. Instead, the command is flagged so
+ * that special handling will be used to send the abort.
+ */
+ cm->cm_flags |= MPR_CM_FLAGS_SATA_ID_TIMEOUT;
+ wakeup(cm);
+}
+
static int
mprsas_volume_add(struct mpr_softc *sc, u16 handle)
{
@@ -1024,15 +1157,13 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc)
path_id_t pathid = cam_sim_path(sassc->sim);
target_id_t targetid;
struct mprsas_target *target;
- struct mprsas_lun *lun;
char path_str[64];
struct timeval cur_time, start_time;
mpr_lock(sc);
/*
- * For each LUN of each target, issue a StartStopUnit command to stop
- * the device.
+ * For each target, issue a StartStopUnit command to stop the device.
*/
sc->SSU_started = TRUE;
sc->SSU_refcount = 0;
@@ -1042,59 +1173,52 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc)
continue;
}
- SLIST_FOREACH(lun, &target->luns, lun_link) {
- ccb = xpt_alloc_ccb_nowait();
- if (ccb == NULL) {
- mpr_unlock(sc);
- mpr_dprint(sc, MPR_FAULT, "Unable to alloc "
- "CCB to stop unit.\n");
+ ccb = xpt_alloc_ccb_nowait();
+ if (ccb == NULL) {
+ mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB to stop "
+ "unit.\n");
+ return;
+ }
+
+ /*
+ * The stop_at_shutdown flag will be set if this device is
+ * a SATA direct-access end device.
+ */
+ if (target->stop_at_shutdown) {
+ if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
+ pathid, targetid, CAM_LUN_WILDCARD) !=
+ CAM_REQ_CMP) {
+ mpr_dprint(sc, MPR_ERROR, "Unable to create "
+ "path to stop unit.\n");
+ xpt_free_ccb(ccb);
return;
}
+ xpt_path_string(ccb->ccb_h.path, path_str,
+ sizeof(path_str));
+
+ mpr_dprint(sc, MPR_INFO, "Sending StopUnit: path %s "
+ "handle %d\n", path_str, target->handle);
/*
- * The stop_at_shutdown flag will be set if this LUN is
- * a SATA direct-access end device.
+ * Issue a START STOP UNIT command for the target.
+ * Increment the SSU counter to be used to count the
+ * number of required replies.
*/
- if (lun->stop_at_shutdown) {
- if (xpt_create_path(&ccb->ccb_h.path,
- xpt_periph, pathid, targetid,
- lun->lun_id) != CAM_REQ_CMP) {
- mpr_dprint(sc, MPR_FAULT, "Unable to "
- "create LUN path to stop unit.\n");
- xpt_free_ccb(ccb);
- mpr_unlock(sc);
- return;
- }
- xpt_path_string(ccb->ccb_h.path, path_str,
- sizeof(path_str));
-
- mpr_dprint(sc, MPR_INFO, "Sending StopUnit: "
- "path %s handle %d\n", path_str,
- target->handle);
-
- /*
- * Issue a START STOP UNIT command for the LUN.
- * Increment the SSU counter to be used to
- * count the number of required replies.
- */
- mpr_dprint(sc, MPR_INFO, "Incrementing SSU "
- "count\n");
- sc->SSU_refcount++;
- ccb->ccb_h.target_id =
- xpt_path_target_id(ccb->ccb_h.path);
- ccb->ccb_h.target_lun = lun->lun_id;
- ccb->ccb_h.ppriv_ptr1 = sassc;
- scsi_start_stop(&ccb->csio,
- /*retries*/0,
- mprsas_stop_unit_done,
- MSG_SIMPLE_Q_TAG,
- /*start*/FALSE,
- /*load/eject*/0,
- /*immediate*/FALSE,
- MPR_SENSE_LEN,
- /*timeout*/10000);
- xpt_action(ccb);
- }
+ mpr_dprint(sc, MPR_INFO, "Incrementing SSU count\n");
+ sc->SSU_refcount++;
+ ccb->ccb_h.target_id =
+ xpt_path_target_id(ccb->ccb_h.path);
+ ccb->ccb_h.ppriv_ptr1 = sassc;
+ scsi_start_stop(&ccb->csio,
+ /*retries*/0,
+ mprsas_stop_unit_done,
+ MSG_SIMPLE_Q_TAG,
+ /*start*/FALSE,
+ /*load/eject*/0,
+ /*immediate*/FALSE,
+ MPR_SENSE_LEN,
+ /*timeout*/10000);
+ xpt_action(ccb);
}
}
@@ -1102,7 +1226,7 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc)
/*
* Wait until all of the SSU commands have completed or time has
- * expired (60 seconds). pause for 100ms each time through. If any
+ * expired (60 seconds). Pause for 100ms each time through. If any
* command times out, the target will be reset in the SCSI command
* timeout routine.
*/
@@ -1112,7 +1236,7 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc)
getmicrotime(&cur_time);
if ((cur_time.tv_sec - start_time.tv_sec) > 60) {
- mpr_dprint(sc, MPR_FAULT, "Time has expired waiting "
+ mpr_dprint(sc, MPR_ERROR, "Time has expired waiting "
"for SSU commands to complete.\n");
break;
}
@@ -1162,6 +1286,8 @@ mprsas_ir_shutdown(struct mpr_softc *sc)
unsigned int id, found_volume = 0;
struct mpr_command *cm;
Mpi2RaidActionRequest_t *action;
+ target_id_t targetid;
+ struct mprsas_target *target;
mpr_dprint(sc, MPR_TRACE, "%s\n", __func__);
@@ -1214,5 +1340,47 @@ mprsas_ir_shutdown(struct mpr_softc *sc)
mpr_free_command(sc, cm);
out:
+ /*
+ * All of the targets must have the correct value set for
+ * 'stop_at_shutdown' for the current 'enable_ssu' sysctl variable.
+ *
+ * The possible values for the 'enable_ssu' variable are:
+ * 0: disable to SSD and HDD
+ * 1: disable only to HDD (default)
+ * 2: disable only to SSD
+ * 3: enable to SSD and HDD
+ * anything else will default to 1.
+ */
+ for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) {
+ target = &sc->sassc->targets[targetid];
+ if (target->handle == 0x0) {
+ continue;
+ }
+
+ if (target->supports_SSU) {
+ switch (sc->enable_ssu) {
+ case MPR_SSU_DISABLE_SSD_DISABLE_HDD:
+ target->stop_at_shutdown = FALSE;
+ break;
+ case MPR_SSU_DISABLE_SSD_ENABLE_HDD:
+ target->stop_at_shutdown = TRUE;
+ if (target->flags & MPR_TARGET_IS_SATA_SSD) {
+ target->stop_at_shutdown = FALSE;
+ }
+ break;
+ case MPR_SSU_ENABLE_SSD_ENABLE_HDD:
+ target->stop_at_shutdown = TRUE;
+ break;
+ case MPR_SSU_ENABLE_SSD_DISABLE_HDD:
+ default:
+ target->stop_at_shutdown = TRUE;
+ if ((target->flags &
+ MPR_TARGET_IS_SATA_SSD) == 0) {
+ target->stop_at_shutdown = FALSE;
+ }
+ break;
+ }
+ }
+ }
mprsas_SSU_to_SATA_devices(sc);
}
diff --git a/sys/dev/mpr/mpr_user.c b/sys/dev/mpr/mpr_user.c
index 60680f5288a3..37d946718b23 100644
--- a/sys/dev/mpr/mpr_user.c
+++ b/sys/dev/mpr/mpr_user.c
@@ -27,10 +27,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD userland interface
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD userland interface
*/
/*-
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,7 +55,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * LSI MPT-Fusion Host Adapter FreeBSD
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
*
* $FreeBSD$
*/
@@ -90,7 +91,7 @@ __FBSDID("$FreeBSD$");
#include <sys/rman.h>
#include <cam/cam.h>
-#include <cam/scsi/scsi_all.h>
+#include <cam/cam_ccb.h>
#include <dev/mpr/mpi/mpi2_type.h>
#include <dev/mpr/mpi/mpi2.h>
@@ -284,8 +285,7 @@ mpr_user_read_cfg_header(struct mpr_softc *sc,
static int
mpr_user_read_cfg_page(struct mpr_softc *sc,
- struct mpr_cfg_page_req *page_req,
- void *buf)
+ struct mpr_cfg_page_req *page_req, void *buf)
{
MPI2_CONFIG_PAGE_HEADER *reqhdr, *hdr;
struct mpr_config_params params;
@@ -328,6 +328,10 @@ mpr_user_read_extcfg_header(struct mpr_softc *sc,
hdr->PageNumber = ext_page_req->header.PageNumber;
hdr->ExtPageType = ext_page_req->header.ExtPageType;
params.page_address = le32toh(ext_page_req->page_address);
+ params.buffer = NULL;
+ params.length = 0;
+ params.callback = NULL;
+
if ((error = mpr_read_config_page(sc, &params)) != 0) {
/*
* Leave the request. Without resetting the chip, it's
@@ -365,8 +369,8 @@ mpr_user_read_extcfg_page(struct mpr_softc *sc,
params.action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
params.page_address = le32toh(ext_page_req->page_address);
hdr->PageVersion = reqhdr->PageVersion;
- hdr->PageNumber = reqhdr->PageNumber;
hdr->PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+ hdr->PageNumber = reqhdr->PageNumber;
hdr->ExtPageType = reqhdr->ExtPageType;
hdr->ExtPageLength = reqhdr->ExtPageLength;
params.buffer = buf;
@@ -541,6 +545,8 @@ mpi_pre_fw_upload(struct mpr_command *cm, struct mpr_usr_command *cmd)
req->ImageOffset = 0;
req->ImageSize = cmd->len;
+ cm->cm_flags |= MPR_CM_FLAGS_DATAIN;
+
return (mpr_push_ieee_sge(cm, &req->SGL, 0));
}
@@ -834,11 +840,22 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
task->TaskMID = cm->cm_desc.Default.SMID;
cm->cm_data = NULL;
- cm->cm_desc.HighPriority.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
+ cm->cm_desc.HighPriority.RequestFlags =
+ MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
cm->cm_complete = NULL;
cm->cm_complete_data = NULL;
- err = mpr_wait_command(sc, cm, 30, CAN_SLEEP);
+ targ = mprsas_find_target_by_handle(sc->sassc, 0,
+ task->DevHandle);
+ if (targ == NULL) {
+ mpr_dprint(sc, MPR_INFO,
+ "%s %d : invalid handle for requested TM 0x%x \n",
+ __func__, __LINE__, task->DevHandle);
+ err = 1;
+ } else {
+ mprsas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD);
+ err = mpr_wait_command(sc, cm, 30, CAN_SLEEP);
+ }
if (err != 0) {
err = EIO;
@@ -1029,7 +1046,7 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data)
if (cm->cm_flags & MPR_CM_FLAGS_DATAIN)
dir = BUS_DMASYNC_POSTREAD;
else if (cm->cm_flags & MPR_CM_FLAGS_DATAOUT)
- dir = BUS_DMASYNC_POSTWRITE;;
+ dir = BUS_DMASYNC_POSTWRITE;
bus_dmamap_sync(sc->buffer_dmat, cm->cm_dmamap, dir);
bus_dmamap_unload(sc->buffer_dmat, cm->cm_dmamap);
@@ -1351,8 +1368,8 @@ done:
}
static int
-mpr_diag_register(struct mpr_softc *sc,
- mpr_fw_diag_register_t *diag_register, uint32_t *return_code)
+mpr_diag_register(struct mpr_softc *sc, mpr_fw_diag_register_t *diag_register,
+ uint32_t *return_code)
{
mpr_fw_diagnostic_buffer_t *pBuffer;
uint8_t extended_type, buffer_type, i;
diff --git a/sys/dev/mpr/mprvar.h b/sys/dev/mpr/mprvar.h
index 9752dcd35f6f..acac44c5baec 100644
--- a/sys/dev/mpr/mprvar.h
+++ b/sys/dev/mpr/mprvar.h
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
- * Copyright (c) 2011-2014 LSI Corp.
+ * Copyright (c) 2011-2015 LSI Corp.
+ * Copyright (c) 2013-2015 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,13 +25,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
+ * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
+ *
* $FreeBSD$
*/
#ifndef _MPRVAR_H
#define _MPRVAR_H
-#define MPR_DRIVER_VERSION "05.255.05.00-fbsd"
+#define MPR_DRIVER_VERSION "09.255.01.00-fbsd"
#define MPR_DB_MAX_WAIT 2500
@@ -47,16 +50,19 @@
#define MPR_FUNCTRACE(sc) \
mpr_dprint((sc), MPR_TRACE, "%s\n", __func__)
-#define CAN_SLEEP 1
-#define NO_SLEEP 0
+#define CAN_SLEEP 1
+#define NO_SLEEP 0
#define MPR_PERIODIC_DELAY 1 /* 1 second heartbeat/watchdog check */
+#define MPR_ATA_ID_TIMEOUT 5 /* 5 second timeout for SATA ID cmd */
#define IFAULT_IOP_OVER_TEMP_THRESHOLD_EXCEEDED 0x2810
#define MPR_SCSI_RI_INVALID_FRAME (0x00000002)
#define MPR_STRING_LENGTH 64
+#define DEFAULT_SPINUP_WAIT 3 /* seconds to wait for spinup */
+
#include <sys/endian.h>
/*
@@ -213,13 +219,14 @@ struct mpr_command {
#define MPR_CM_FLAGS_CHAIN_FAILED (1 << 8)
#define MPR_CM_FLAGS_ERROR_MASK MPR_CM_FLAGS_CHAIN_FAILED
#define MPR_CM_FLAGS_USE_CCB (1 << 9)
+#define MPR_CM_FLAGS_SATA_ID_TIMEOUT (1 << 10)
u_int cm_state;
#define MPR_CM_STATE_FREE 0
#define MPR_CM_STATE_BUSY 1
#define MPR_CM_STATE_TIMEDOUT 2
bus_dmamap_t cm_dmamap;
struct scsi_sense_data *cm_sense;
- TAILQ_HEAD(, mpr_chain) cm_chain_list;
+ TAILQ_HEAD(, mpr_chain) cm_chain_list;
uint32_t cm_req_busaddr;
uint32_t cm_sense_busaddr;
struct callout cm_callout;
@@ -256,6 +263,8 @@ struct mpr_softc {
int chain_free;
int max_chains;
int chain_free_lowwater;
+ u_int enable_ssu;
+ int spinup_wait_time;
#if __FreeBSD_version >= 900030
uint64_t chain_alloc_fail;
#endif
@@ -270,7 +279,7 @@ struct mpr_softc {
char tmp_string[MPR_STRING_LENGTH];
TAILQ_HEAD(, mpr_command) req_list;
TAILQ_HEAD(, mpr_command) high_priority_req_list;
- TAILQ_HEAD(, mpr_chain) chain_list;
+ TAILQ_HEAD(, mpr_chain) chain_list;
TAILQ_HEAD(, mpr_command) tm_list;
int replypostindex;
int replyfreeindex;
@@ -291,7 +300,7 @@ struct mpr_softc {
uint8_t event_mask[16];
TAILQ_HEAD(, mpr_event_handle) event_list;
- struct mpr_event_handle *mpr_log_eh;
+ struct mpr_event_handle *mpr_log_eh;
struct mtx mpr_mtx;
struct intr_config_hook mpr_ich;
@@ -565,6 +574,11 @@ mpr_unlock(struct mpr_softc *sc)
#define MPR_MAPPING (1 << 9) /* Trace device mappings */
#define MPR_TRACE (1 << 10) /* Function-by-function trace */
+#define MPR_SSU_DISABLE_SSD_DISABLE_HDD 0
+#define MPR_SSU_ENABLE_SSD_DISABLE_HDD 1
+#define MPR_SSU_DISABLE_SSD_ENABLE_HDD 2
+#define MPR_SSU_ENABLE_SSD_ENABLE_HDD 3
+
#define mpr_printf(sc, args...) \
device_printf((sc)->mpr_dev, ##args)
@@ -600,9 +614,6 @@ do { \
#define MPR_EVENTFIELD(sc, facts, attr, fmt) \
mpr_dprint_field((sc), MPR_EVENT, #attr ": " #fmt "\n", (facts)->attr)
-#define CAN_SLEEP 1
-#define NO_SLEEP 0
-
static __inline void
mpr_from_u64(uint64_t data, U64 *mpr)
{
@@ -613,7 +624,6 @@ mpr_from_u64(uint64_t data, U64 *mpr)
static __inline uint64_t
mpr_to_u64(U64 *data)
{
-
return (((uint64_t)le32toh(data->High) << 32) | le32toh(data->Low));
}
@@ -727,6 +737,12 @@ void mprsas_prepare_volume_remove(struct mprsas_softc *sassc,
int mprsas_startup(struct mpr_softc *sc);
struct mprsas_target * mprsas_find_target_by_handle(struct mprsas_softc *,
int, uint16_t);
+void mprsas_realloc_targets(struct mpr_softc *sc, int maxtargets);
+struct mpr_command * mprsas_alloc_tm(struct mpr_softc *sc);
+void mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm);
+void mprsas_release_simq_reinit(struct mprsas_softc *sassc);
+int mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm,
+ uint8_t type);
SYSCTL_DECL(_hw_mpr);
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c
index 5997dbc96194..09975005eec2 100644
--- a/sys/dev/mwl/if_mwl.c
+++ b/sys/dev/mwl/if_mwl.c
@@ -113,9 +113,9 @@ static int mwl_key_delete(struct ieee80211vap *,
static int mwl_key_set(struct ieee80211vap *, const struct ieee80211_key *,
const uint8_t mac[IEEE80211_ADDR_LEN]);
static int mwl_mode_init(struct mwl_softc *);
-static void mwl_update_mcast(struct ifnet *);
-static void mwl_update_promisc(struct ifnet *);
-static void mwl_updateslot(struct ifnet *);
+static void mwl_update_mcast(struct ieee80211com *);
+static void mwl_update_promisc(struct ieee80211com *);
+static void mwl_updateslot(struct ieee80211com *);
static int mwl_beacon_setup(struct ieee80211vap *);
static void mwl_beacon_update(struct ieee80211vap *, int);
#ifdef MWL_HOST_PS_SUPPORT
@@ -413,6 +413,8 @@ mwl_attach(uint16_t devid, struct mwl_softc *sc)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(sc->sc_dev);
/* XXX not right but it's not used anywhere important */
ic->ic_phytype = IEEE80211_T_OFDM;
ic->ic_opmode = IEEE80211_M_STA;
@@ -1843,9 +1845,9 @@ mwl_mode_init(struct mwl_softc *sc)
* Callback from the 802.11 layer after a multicast state change.
*/
static void
-mwl_update_mcast(struct ifnet *ifp)
+mwl_update_mcast(struct ieee80211com *ic)
{
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
mwl_setmcastfilter(sc);
}
@@ -1858,11 +1860,12 @@ mwl_update_mcast(struct ifnet *ifp)
* mode when operating in hostap mode to do ACS).
*/
static void
-mwl_update_promisc(struct ifnet *ifp)
+mwl_update_promisc(struct ieee80211com *ic)
{
- struct mwl_softc *sc = ifp->if_softc;
+ struct mwl_softc *sc = ic->ic_softc;
- mwl_hal_setpromisc(sc->sc_mh, (ifp->if_flags & IFF_PROMISC) != 0);
+ mwl_hal_setpromisc(sc->sc_mh,
+ (ic->ic_ifp->if_flags & IFF_PROMISC) != 0);
}
/*
@@ -1872,15 +1875,14 @@ mwl_update_promisc(struct ifnet *ifp)
* like slot time and preamble.
*/
static void
-mwl_updateslot(struct ifnet *ifp)
+mwl_updateslot(struct ieee80211com *ic)
{
- struct mwl_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct mwl_softc *sc = ic->ic_softc;
struct mwl_hal *mh = sc->sc_mh;
int prot;
/* NB: can be called early; suppress needless cmds */
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
/*
@@ -1938,7 +1940,7 @@ mwl_beacon_update(struct ieee80211vap *vap, int item)
KASSERT(hvap != NULL, ("no beacon"));
switch (item) {
case IEEE80211_BEACON_ERP:
- mwl_updateslot(ic->ic_ifp);
+ mwl_updateslot(ic);
break;
case IEEE80211_BEACON_HTINFO:
mwl_hal_setnprotmode(hvap,
diff --git a/sys/dev/nand/nfc_rb.c b/sys/dev/nand/nfc_rb.c
index 64f888a2a157..20a4026304e8 100644
--- a/sys/dev/nand/nfc_rb.c
+++ b/sys/dev/nand/nfc_rb.c
@@ -49,6 +49,9 @@ __FBSDID("$FreeBSD$");
#include <dev/nand/nand.h>
#include <dev/nand/nandbus.h>
+
+#include <powerpc/mpc85xx/mpc85xx.h>
+
#include "nfc_if.h"
#include "gpio_if.h"
@@ -128,6 +131,7 @@ rb_nand_attach(device_t dev)
struct rb_nand_softc *sc;
phandle_t node;
uint32_t ale[2],cle[2],nce[2],rdy[2];
+ u_long size,start;
int err;
sc = device_get_softc(dev);
@@ -168,6 +172,14 @@ rb_nand_attach(device_t dev)
return (ENXIO);
}
+ start = rman_get_start(sc->sc_mem);
+ size = rman_get_size(sc->sc_mem);
+ if (law_enable(OCP85XX_TGTIF_LBC, start, size) != 0) {
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->sc_mem);
+ device_printf(dev, "could not allocate local address window.\n");
+ return (ENXIO);
+ }
+
nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL);
err = nandbus_create(dev);
diff --git a/sys/dev/netmap/if_em_netmap.h b/sys/dev/netmap/if_em_netmap.h
index 15e9be54315d..99eaa6f01319 100644
--- a/sys/dev/netmap/if_em_netmap.h
+++ b/sys/dev/netmap/if_em_netmap.h
@@ -70,7 +70,7 @@ em_netmap_unblock_tasks(struct adapter *adapter)
struct rx_ring *rxr = adapter->rx_rings;
int i;
- for (i = 0; i < adapter->num_queues; i++) {
+ for (i = 0; i < adapter->num_queues; i++, txr++, rxr++) {
taskqueue_unblock(txr->tq);
taskqueue_unblock(rxr->tq);
}
diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c
index 5063930d5a9e..a9261cee1346 100644
--- a/sys/dev/ofw/ofw_bus_subr.c
+++ b/sys/dev/ofw/ofw_bus_subr.c
@@ -503,6 +503,28 @@ ofw_bus_intr_to_rl(device_t dev, phandle_t node,
}
phandle_t
+ofw_bus_find_child(phandle_t start, const char *child_name)
+{
+ char *name;
+ int ret;
+ phandle_t child;
+
+ for (child = OF_child(start); child != 0; child = OF_peer(child)) {
+ ret = OF_getencprop_alloc(child, "name", sizeof(*name), (void **)&name);
+ if (ret == -1)
+ continue;
+ if (strcmp(name, child_name) == 0) {
+ free(name, M_OFWPROP);
+ return (child);
+ }
+
+ free(name, M_OFWPROP);
+ }
+
+ return (0);
+}
+
+phandle_t
ofw_bus_find_compatible(phandle_t node, const char *onecompat)
{
phandle_t child, ret;
diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h
index be35711b0281..bbeda7f5533c 100644
--- a/sys/dev/ofw/ofw_bus_subr.h
+++ b/sys/dev/ofw/ofw_bus_subr.h
@@ -104,4 +104,7 @@ int ofw_bus_has_prop(device_t, const char *);
/* Helper to search for a child with a given compat prop */
phandle_t ofw_bus_find_compatible(phandle_t, const char *);
+/* Helper to search for a child with a given name */
+phandle_t ofw_bus_find_child(phandle_t, const char *);
+
#endif /* !_DEV_OFW_OFW_BUS_SUBR_H_ */
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index b4c6151210db..98b6b53a0724 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -2389,7 +2389,7 @@ pci_set_powerstate_method(device_t dev, device_t child, int state)
struct pci_devinfo *dinfo = device_get_ivars(child);
pcicfgregs *cfg = &dinfo->cfg;
uint16_t status;
- int result, oldstate, highest, delay;
+ int oldstate, highest, delay;
if (cfg->pp.pp_cap == 0)
return (EOPNOTSUPP);
@@ -2424,7 +2424,6 @@ pci_set_powerstate_method(device_t dev, device_t child, int state)
delay = 0;
status = PCI_READ_CONFIG(dev, child, cfg->pp.pp_status, 2)
& ~PCIM_PSTAT_DMASK;
- result = 0;
switch (state) {
case PCI_POWERSTATE_D0:
status |= PCIM_PSTAT_D0;
@@ -2989,7 +2988,6 @@ static void
pci_ata_maps(device_t bus, device_t dev, struct resource_list *rl, int force,
uint32_t prefetchmask)
{
- struct resource *r;
int rid, type, progif;
#if 0
/* if this device supports PCI native addressing use it */
@@ -3012,11 +3010,11 @@ pci_ata_maps(device_t bus, device_t dev, struct resource_list *rl, int force,
} else {
rid = PCIR_BAR(0);
resource_list_add(rl, type, rid, 0x1f0, 0x1f7, 8);
- r = resource_list_reserve(rl, bus, dev, type, &rid, 0x1f0,
+ (void)resource_list_reserve(rl, bus, dev, type, &rid, 0x1f0,
0x1f7, 8, 0);
rid = PCIR_BAR(1);
resource_list_add(rl, type, rid, 0x3f6, 0x3f6, 1);
- r = resource_list_reserve(rl, bus, dev, type, &rid, 0x3f6,
+ (void)resource_list_reserve(rl, bus, dev, type, &rid, 0x3f6,
0x3f6, 1, 0);
}
if (progif & PCIP_STORAGE_IDE_MODESEC) {
@@ -3027,11 +3025,11 @@ pci_ata_maps(device_t bus, device_t dev, struct resource_list *rl, int force,
} else {
rid = PCIR_BAR(2);
resource_list_add(rl, type, rid, 0x170, 0x177, 8);
- r = resource_list_reserve(rl, bus, dev, type, &rid, 0x170,
+ (void)resource_list_reserve(rl, bus, dev, type, &rid, 0x170,
0x177, 8, 0);
rid = PCIR_BAR(3);
resource_list_add(rl, type, rid, 0x376, 0x376, 1);
- r = resource_list_reserve(rl, bus, dev, type, &rid, 0x376,
+ (void)resource_list_reserve(rl, bus, dev, type, &rid, 0x376,
0x376, 1, 0);
}
pci_add_map(bus, dev, PCIR_BAR(4), rl, force,
@@ -3727,7 +3725,6 @@ pci_detach(device_t dev)
static void
pci_set_power_child(device_t dev, device_t child, int state)
{
- struct pci_devinfo *dinfo;
device_t pcib;
int dstate;
@@ -3739,7 +3736,6 @@ pci_set_power_child(device_t dev, device_t child, int state)
* are handled separately.
*/
pcib = device_get_parent(dev);
- dinfo = device_get_ivars(child);
dstate = state;
if (device_is_attached(child) &&
PCIB_POWER_FOR_SLEEP(pcib, child, &dstate) == 0)
diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c
new file mode 100644
index 000000000000..04dc8d3cd953
--- /dev/null
+++ b/sys/dev/pci/pci_host_generic.c
@@ -0,0 +1,626 @@
+/*-
+ * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
+ * Copyright (c) 2014 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Semihalf under
+ * the sponsorship of the FreeBSD Foundation.
+ *
+ * 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.
+ */
+
+/* Generic ECAM PCIe driver */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/rman.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/cpuset.h>
+#include <sys/rwlock.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcib_private.h>
+#include <machine/cpu.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
+#include <vm/vm_page.h>
+
+#include "pcib_if.h"
+
+/* Assembling ECAM Configuration Address */
+#define PCIE_BUS_SHIFT 20
+#define PCIE_SLOT_SHIFT 15
+#define PCIE_FUNC_SHIFT 12
+#define PCIE_BUS_MASK 0xFF
+#define PCIE_SLOT_MASK 0x1F
+#define PCIE_FUNC_MASK 0x07
+#define PCIE_REG_MASK 0xFFF
+
+#define PCIE_ADDR_OFFSET(bus, slot, func, reg) \
+ ((((bus) & PCIE_BUS_MASK) << PCIE_BUS_SHIFT) | \
+ (((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT) | \
+ (((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT) | \
+ ((reg) & PCIE_REG_MASK))
+
+#define MAX_RANGES_TUPLES 5
+#define MIN_RANGES_TUPLES 2
+
+#define PCI_IO_WINDOW_OFFSET 0x1000
+#define PCI_IRQ_START 32
+#define PCI_IRQ_END (PCI_IRQ_START + 4)
+
+#define SPACE_CODE_SHIFT 24
+#define SPACE_CODE_MASK 0x3
+#define SPACE_CODE_IO_SPACE 0x1
+#define PROPS_CELL_SIZE 1
+#define PCI_ADDR_CELL_SIZE 2
+
+struct pcie_range {
+ uint64_t pci_base;
+ uint64_t phys_base;
+ uint64_t size;
+ uint64_t flags;
+#define FLAG_IO (1 << 0)
+#define FLAG_MEM (1 << 1)
+};
+
+struct generic_pcie_softc {
+ struct pcie_range ranges[MAX_RANGES_TUPLES];
+ int nranges;
+ struct rman mem_rman;
+ struct rman io_rman;
+ struct rman irq_rman;
+ struct resource *res;
+ struct resource *res1;
+ int ecam;
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+ device_t dev;
+ bus_space_handle_t ioh;
+};
+
+/* Forward prototypes */
+
+static int generic_pcie_probe(device_t dev);
+static int generic_pcie_attach(device_t dev);
+static int parse_pci_mem_ranges(struct generic_pcie_softc *sc);
+static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, int bytes);
+static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, uint32_t val, int bytes);
+static int generic_pcie_maxslots(device_t dev);
+static int generic_pcie_read_ivar(device_t dev, device_t child, int index,
+ uintptr_t *result);
+static int generic_pcie_write_ivar(device_t dev, device_t child, int index,
+ uintptr_t value);
+static struct resource *generic_pcie_alloc_resource(device_t dev,
+ device_t child, int type, int *rid, u_long start, u_long end,
+ u_long count, u_int flags);
+static int generic_pcie_release_resource(device_t dev, device_t child,
+ int type, int rid, struct resource *res);
+
+static int
+generic_pcie_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_is_compatible(dev, "pci-host-ecam-generic")) {
+ device_set_desc(dev, "Generic PCI host controller");
+ return (BUS_PROBE_DEFAULT);
+ }
+
+ return (ENXIO);
+}
+
+static int
+generic_pcie_attach(device_t dev)
+{
+ struct generic_pcie_softc *sc;
+ uint64_t phys_base;
+ uint64_t pci_base;
+ uint64_t size;
+ int error;
+ int tuple;
+ int rid;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ rid = 0;
+ sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+ if (sc->res == NULL) {
+ device_printf(dev, "could not map memory.\n");
+ return (ENXIO);
+ }
+
+ sc->bst = rman_get_bustag(sc->res);
+ sc->bsh = rman_get_bushandle(sc->res);
+
+ sc->mem_rman.rm_type = RMAN_ARRAY;
+ sc->mem_rman.rm_descr = "PCIe Memory";
+ sc->io_rman.rm_type = RMAN_ARRAY;
+ sc->io_rman.rm_descr = "PCIe IO window";
+
+ /* Retrieve 'ranges' property from FDT */
+ if (bootverbose)
+ device_printf(dev, "parsing FDT for ECAM%d:\n",
+ sc->ecam);
+ if (parse_pci_mem_ranges(sc))
+ return (ENXIO);
+
+ /* Initialize rman and allocate memory regions */
+ error = rman_init(&sc->mem_rman);
+ if (error) {
+ device_printf(dev, "rman_init() failed. error = %d\n", error);
+ return (error);
+ }
+
+ error = rman_init(&sc->io_rman);
+ if (error) {
+ device_printf(dev, "rman_init() failed. error = %d\n", error);
+ return (error);
+ }
+
+ for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
+ phys_base = sc->ranges[tuple].phys_base;
+ pci_base = sc->ranges[tuple].pci_base;
+ size = sc->ranges[tuple].size;
+ if (phys_base == 0 || size == 0)
+ continue; /* empty range element */
+ if (sc->ranges[tuple].flags & FLAG_MEM) {
+ error = rman_manage_region(&sc->mem_rman,
+ phys_base,
+ phys_base + size);
+ } else if (sc->ranges[tuple].flags & FLAG_IO) {
+ error = rman_manage_region(&sc->io_rman,
+ pci_base + PCI_IO_WINDOW_OFFSET,
+ pci_base + PCI_IO_WINDOW_OFFSET + size);
+ } else
+ continue;
+ if (error) {
+ device_printf(dev, "rman_manage_region() failed."
+ "error = %d\n", error);
+ rman_fini(&sc->mem_rman);
+ return (error);
+ }
+ }
+
+ /* TODO: get IRQ numbers from FDT */
+ sc->irq_rman.rm_type = RMAN_ARRAY;
+ sc->irq_rman.rm_descr = "Generic PCIe IRQs";
+ if (rman_init(&sc->irq_rman) != 0 ||
+ rman_manage_region(&sc->irq_rman, PCI_IRQ_START,
+ PCI_IRQ_END) != 0) {
+ panic("Generic PCI: failed to set up IRQ rman");
+ }
+
+ device_add_child(dev, "pci", -1);
+ return (bus_generic_attach(dev));
+}
+
+static int
+parse_pci_mem_ranges(struct generic_pcie_softc *sc)
+{
+ pcell_t pci_addr_cells, parent_addr_cells;
+ pcell_t attributes, size_cells;
+ cell_t *base_ranges;
+ int nbase_ranges;
+ phandle_t node;
+ int i, j, k;
+ int tuple;
+
+ node = ofw_bus_get_node(sc->dev);
+
+ OF_getencprop(node, "#address-cells", &pci_addr_cells,
+ sizeof(pci_addr_cells));
+ OF_getencprop(node, "#size-cells", &size_cells,
+ sizeof(size_cells));
+ OF_getencprop(OF_parent(node), "#address-cells", &parent_addr_cells,
+ sizeof(parent_addr_cells));
+
+ if (parent_addr_cells != 2 || pci_addr_cells != 3 || size_cells != 2) {
+ device_printf(sc->dev,
+ "Unexpected number of address or size cells in FDT\n");
+ return (ENXIO);
+ }
+
+ nbase_ranges = OF_getproplen(node, "ranges");
+ sc->nranges = nbase_ranges / sizeof(cell_t) /
+ (parent_addr_cells + pci_addr_cells + size_cells);
+ base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
+ OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
+
+ for (i = 0, j = 0; i < sc->nranges; i++) {
+ attributes = (base_ranges[j++] >> SPACE_CODE_SHIFT) & \
+ SPACE_CODE_MASK;
+ if (attributes == SPACE_CODE_IO_SPACE) {
+ sc->ranges[i].flags |= FLAG_IO;
+ } else {
+ sc->ranges[i].flags |= FLAG_MEM;
+ }
+
+ sc->ranges[i].pci_base = 0;
+ for (k = 0; k < (pci_addr_cells - 1); k++) {
+ sc->ranges[i].pci_base <<= 32;
+ sc->ranges[i].pci_base |= base_ranges[j++];
+ }
+ sc->ranges[i].phys_base = 0;
+ for (k = 0; k < parent_addr_cells; k++) {
+ sc->ranges[i].phys_base <<= 32;
+ sc->ranges[i].phys_base |= base_ranges[j++];
+ }
+ sc->ranges[i].size = 0;
+ for (k = 0; k < size_cells; k++) {
+ sc->ranges[i].size <<= 32;
+ sc->ranges[i].size |= base_ranges[j++];
+ }
+ }
+
+ for (; i < MAX_RANGES_TUPLES; i++) {
+ /* zero-fill remaining tuples to mark empty elements in array */
+ sc->ranges[i].pci_base = 0;
+ sc->ranges[i].phys_base = 0;
+ sc->ranges[i].size = 0;
+ }
+
+ if (bootverbose) {
+ for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
+ device_printf(sc->dev,
+ "\tPCI addr: 0x%jx, CPU addr: 0x%jx, Size: 0x%jx\n",
+ sc->ranges[tuple].pci_base,
+ sc->ranges[tuple].phys_base,
+ sc->ranges[tuple].size);
+ }
+ }
+
+ free(base_ranges, M_DEVBUF);
+ return (0);
+}
+
+static uint32_t
+generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, int bytes)
+{
+ struct generic_pcie_softc *sc;
+ bus_space_handle_t h;
+ bus_space_tag_t t;
+ uint64_t offset;
+ uint32_t data;
+
+ if (bus > 255 || slot > 31 || func > 7 || reg > 4095)
+ return (~0U);
+
+ sc = device_get_softc(dev);
+
+ offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
+ t = sc->bst;
+ h = sc->bsh;
+
+ switch (bytes) {
+ case 1:
+ data = bus_space_read_1(t, h, offset);
+ break;
+ case 2:
+ data = le16toh(bus_space_read_2(t, h, offset));
+ break;
+ case 4:
+ data = le32toh(bus_space_read_4(t, h, offset));
+ break;
+ default:
+ return (~0U);
+ }
+
+ if (reg == PCIR_INTLINE) {
+ data += PCI_IRQ_START;
+ }
+
+ return (data);
+}
+
+static void
+generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, uint32_t val, int bytes)
+{
+ struct generic_pcie_softc *sc;
+ bus_space_handle_t h;
+ bus_space_tag_t t;
+ uint64_t offset;
+
+ if (bus > 255 || slot > 31 || func > 7 || reg > 4095)
+ return;
+
+ sc = device_get_softc(dev);
+
+ offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
+
+ t = sc->bst;
+ h = sc->bsh;
+
+ switch (bytes) {
+ case 1:
+ bus_space_write_1(t, h, offset, val);
+ break;
+ case 2:
+ bus_space_write_2(t, h, offset, htole16(val));
+ break;
+ case 4:
+ bus_space_write_4(t, h, offset, htole32(val));
+ break;
+ default:
+ return;
+ }
+}
+
+static int
+generic_pcie_maxslots(device_t dev)
+{
+
+ return (31); /* max slots per bus acc. to standard */
+}
+
+static int
+generic_pcie_read_ivar(device_t dev, device_t child, int index,
+ uintptr_t *result)
+{
+ struct generic_pcie_softc *sc;
+ int secondary_bus;
+
+ sc = device_get_softc(dev);
+
+ if (index == PCIB_IVAR_BUS) {
+ /* this pcib adds only pci bus 0 as child */
+ secondary_bus = 0;
+ *result = secondary_bus;
+ return (0);
+
+ }
+
+ if (index == PCIB_IVAR_DOMAIN) {
+ *result = sc->ecam;
+ return (0);
+ }
+
+ device_printf(dev, "ERROR: Unknown index.\n");
+ return (ENOENT);
+}
+
+static int
+generic_pcie_write_ivar(device_t dev, device_t child, int index,
+ uintptr_t value)
+{
+
+ return (ENOENT);
+}
+
+static struct rman *
+generic_pcie_rman(struct generic_pcie_softc *sc, int type)
+{
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return (&sc->io_rman);
+ case SYS_RES_MEMORY:
+ return (&sc->mem_rman);
+ case SYS_RES_IRQ:
+ return (&sc->irq_rman);
+ default:
+ break;
+ }
+
+ return (NULL);
+}
+
+static int
+generic_pcie_release_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *res)
+{
+ struct generic_pcie_softc *sc;
+ struct rman *rm;
+
+ sc = device_get_softc(dev);
+
+ rm = generic_pcie_rman(sc, type);
+ if (rm != NULL) {
+ KASSERT(rman_is_region_manager(res, rm), ("rman mismatch"));
+ rman_release_resource(res);
+ }
+
+ return (bus_generic_release_resource(dev, child, type, rid, res));
+}
+
+static struct resource *
+generic_pcie_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct generic_pcie_softc *sc;
+ struct resource *res;
+ struct rman *rm;
+
+ sc = device_get_softc(dev);
+
+ rm = generic_pcie_rman(sc, type);
+ if (rm == NULL)
+ return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+ type, rid, start, end, count, flags));
+
+ if (bootverbose) {
+ device_printf(dev,
+ "rman_reserve_resource: start=%#lx, end=%#lx, count=%#lx\n",
+ start, end, count);
+ }
+
+ res = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (res == NULL)
+ goto fail;
+
+ rman_set_rid(res, *rid);
+
+ if (flags & RF_ACTIVE)
+ if (bus_activate_resource(child, type, *rid, res)) {
+ rman_release_resource(res);
+ goto fail;
+ }
+
+ return (res);
+
+fail:
+ if (bootverbose) {
+ device_printf(dev, "%s FAIL: type=%d, rid=%d, "
+ "start=%016lx, end=%016lx, count=%016lx, flags=%x\n",
+ __func__, type, *rid, start, end, count, flags);
+ }
+
+ return (NULL);
+}
+
+static int
+generic_pcie_adjust_resource(device_t dev, device_t child, int type,
+ struct resource *res, u_long start, u_long end)
+{
+ struct generic_pcie_softc *sc;
+ struct rman *rm;
+
+ sc = device_get_softc(dev);
+
+ rm = generic_pcie_rman(sc, type);
+ if (rm != NULL)
+ return (rman_adjust_resource(res, start, end));
+ return (bus_generic_adjust_resource(dev, child, type, res, start, end));
+}
+
+static int
+generic_pcie_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct generic_pcie_softc *sc;
+ uint64_t phys_base;
+ uint64_t pci_base;
+ uint64_t size;
+ int found;
+ int res;
+ int i;
+
+ sc = device_get_softc(dev);
+
+ if ((res = rman_activate_resource(r)) != 0)
+ return (res);
+
+ switch(type) {
+ case SYS_RES_IOPORT:
+ found = 0;
+ for (i = 0; i < MAX_RANGES_TUPLES; i++) {
+ pci_base = sc->ranges[i].pci_base;
+ phys_base = sc->ranges[i].phys_base;
+ size = sc->ranges[i].size;
+
+ if ((rid > pci_base) && (rid < (pci_base + size))) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ rman_set_start(r, rman_get_start(r) + phys_base);
+ BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child,
+ type, rid, r);
+ } else {
+ device_printf(dev, "Failed to activate IOPORT resource\n");
+ res = 0;
+ }
+ break;
+ case SYS_RES_MEMORY:
+ BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type, rid, r);
+ break;
+ default:
+ break;
+ }
+
+ return (res);
+}
+
+static int
+generic_pcie_deactivate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ struct generic_pcie_softc *sc;
+ vm_offset_t vaddr;
+ int res;
+
+ sc = device_get_softc(dev);
+
+ if ((res = rman_deactivate_resource(r)) != 0)
+ return (res);
+
+ switch(type) {
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ vaddr = (vm_offset_t)rman_get_virtual(r);
+ pmap_unmapdev(vaddr, rman_get_size(r));
+ break;
+ default:
+ break;
+ }
+
+ return (res);
+}
+
+static device_method_t generic_pcie_methods[] = {
+ DEVMETHOD(device_probe, generic_pcie_probe),
+ DEVMETHOD(device_attach, generic_pcie_attach),
+ DEVMETHOD(bus_read_ivar, generic_pcie_read_ivar),
+ DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar),
+ DEVMETHOD(bus_alloc_resource, generic_pcie_alloc_resource),
+ DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource),
+ DEVMETHOD(bus_release_resource, generic_pcie_release_resource),
+ DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+ DEVMETHOD(pcib_maxslots, generic_pcie_maxslots),
+ DEVMETHOD(pcib_read_config, generic_pcie_read_config),
+ DEVMETHOD(pcib_write_config, generic_pcie_write_config),
+ DEVMETHOD_END
+};
+
+static driver_t generic_pcie_driver = {
+ "pcib",
+ generic_pcie_methods,
+ sizeof(struct generic_pcie_softc),
+};
+
+static devclass_t generic_pcie_devclass;
+
+DRIVER_MODULE(pcib, simplebus, generic_pcie_driver,
+generic_pcie_devclass, 0, 0);
+DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver,
+generic_pcie_devclass, 0, 0);
diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m
index 9f97d9a86f4e..aeeff2cf3258 100644
--- a/sys/dev/pci/pci_if.m
+++ b/sys/dev/pci/pci_if.m
@@ -214,22 +214,6 @@ METHOD int iov_detach {
device_t child;
};
-METHOD int init_iov {
- device_t dev;
- uint16_t num_vfs;
- const struct nvlist *config;
-};
-
-METHOD void uninit_iov {
- device_t dev;
-};
-
-METHOD int add_vf {
- device_t dev;
- uint16_t vfnum;
- const struct nvlist *config;
-};
-
METHOD device_t create_iov_child {
device_t bus;
device_t pf;
@@ -237,4 +221,3 @@ METHOD device_t create_iov_child {
uint16_t vid;
uint16_t did;
} DEFAULT null_create_iov_child;
-
diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c
index 4672e55e5996..58e692649df5 100644
--- a/sys/dev/pci/pci_iov.c
+++ b/sys/dev/pci/pci_iov.c
@@ -53,11 +53,11 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
+#include <dev/pci/pci_iov.h>
#include <dev/pci/pci_private.h>
#include <dev/pci/pci_iov_private.h>
#include <dev/pci/schema_private.h>
-#include "pci_if.h"
#include "pcib_if.h"
static MALLOC_DEFINE(M_SRIOV, "sr_iov", "PCI SR-IOV allocations");
@@ -483,13 +483,13 @@ pci_iov_config_page_size(struct pci_devinfo *dinfo)
}
static int
-pci_init_iov(device_t dev, uint16_t num_vfs, const nvlist_t *config)
+pci_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *config)
{
const nvlist_t *device, *driver_config;
device = nvlist_get_nvlist(config, PF_CONFIG_NAME);
driver_config = nvlist_get_nvlist(device, DRIVER_CONFIG_NAME);
- return (PCI_INIT_IOV(dev, num_vfs, driver_config));
+ return (PCI_IOV_INIT(dev, num_vfs, driver_config));
}
static int
@@ -595,7 +595,7 @@ pci_iov_enumerate_vfs(struct pci_devinfo *dinfo, const nvlist_t *config,
pci_iov_add_bars(iov, vfinfo);
- error = PCI_ADD_VF(dev, i, driver_config);
+ error = PCI_IOV_ADD_VF(dev, i, driver_config);
if (error != 0) {
device_printf(dev, "Failed to add VF %d\n", i);
pci_delete_child(bus, vf);
@@ -652,7 +652,7 @@ pci_iov_config(struct cdev *cdev, struct pci_iov_arg *arg)
if (error != 0)
goto out;
- error = pci_init_iov(dev, num_vfs, config);
+ error = pci_iov_init(dev, num_vfs, config);
if (error != 0)
goto out;
iov_inited = 1;
@@ -700,7 +700,7 @@ pci_iov_config(struct cdev *cdev, struct pci_iov_arg *arg)
return (0);
out:
if (iov_inited)
- PCI_UNINIT_IOV(dev);
+ PCI_IOV_UNINIT(dev);
for (i = 0; i <= PCIR_MAX_BAR_0; i++) {
if (iov->iov_bar[i].res != NULL) {
@@ -793,7 +793,7 @@ pci_iov_delete(struct cdev *cdev)
if (pci_iov_is_child_vf(iov, vf))
pci_delete_child(bus, vf);
}
- PCI_UNINIT_IOV(dev);
+ PCI_IOV_UNINIT(dev);
iov_ctl = IOV_READ(dinfo, PCIR_SRIOV_CTL, 2);
iov_ctl &= ~(PCIM_SRIOV_VF_EN | PCIM_SRIOV_VF_MSE);
diff --git a/sys/dev/pci/pci_iov.h b/sys/dev/pci/pci_iov.h
new file mode 100644
index 000000000000..fd2f8fba8876
--- /dev/null
+++ b/sys/dev/pci/pci_iov.h
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2013-2015 Sandvine Inc.
+ * 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$
+ */
+
+#ifndef _PCI_IOV_H_
+#define _PCI_IOV_H_
+
+#include "pci_iov_if.h"
+
+struct nvlist;
+
+static __inline int
+pci_iov_attach(device_t dev, struct nvlist *pf_schema, struct nvlist *vf_schema)
+{
+ return (PCI_IOV_ATTACH(device_get_parent(dev), dev, pf_schema,
+ vf_schema));
+}
+
+static __inline int
+pci_iov_detach(device_t dev)
+{
+ return (PCI_IOV_DETACH(device_get_parent(dev), dev));
+}
+
+#endif /* !_PCI_IOV_H_ */
diff --git a/sys/dev/pci/pci_iov_if.m b/sys/dev/pci/pci_iov_if.m
new file mode 100644
index 000000000000..3b6796badcec
--- /dev/null
+++ b/sys/dev/pci/pci_iov_if.m
@@ -0,0 +1,52 @@
+#-
+# Copyright (c) 2013-2015 Sandvine Inc.
+# 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$
+#
+
+#include <sys/bus.h>
+
+INTERFACE pci_iov;
+
+HEADER {
+ struct nvlist;
+}
+
+
+METHOD int init {
+ device_t dev;
+ uint16_t num_vfs;
+ const struct nvlist *config;
+};
+
+METHOD void uninit {
+ device_t dev;
+};
+
+METHOD int add_vf {
+ device_t dev;
+ uint16_t vfnum;
+ const struct nvlist *config;
+};
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 2fd76b6bf8cd..7f2e95836a30 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -39,8 +39,6 @@
typedef uint64_t pci_addr_t;
-struct nvlist;
-
/* Config registers for PCI-PCI and PCI-Cardbus bridges. */
struct pcicfg_bridge {
uint8_t br_seclat;
@@ -536,19 +534,6 @@ pci_child_added(device_t dev)
return (PCI_CHILD_ADDED(device_get_parent(dev), dev));
}
-static __inline int
-pci_iov_attach(device_t dev, struct nvlist *pf_schema, struct nvlist *vf_schema)
-{
- return (PCI_IOV_ATTACH(device_get_parent(dev), dev, pf_schema,
- vf_schema));
-}
-
-static __inline int
-pci_iov_detach(device_t dev)
-{
- return (PCI_IOV_DETACH(device_get_parent(dev), dev));
-}
-
device_t pci_find_bsf(uint8_t, uint8_t, uint8_t);
device_t pci_find_dbsf(uint32_t, uint8_t, uint8_t, uint8_t);
device_t pci_find_device(uint16_t, uint16_t);
diff --git a/sys/dev/pci/vga_pci.c b/sys/dev/pci/vga_pci.c
index 65332c36bda7..0c49ca09c324 100644
--- a/sys/dev/pci/vga_pci.c
+++ b/sys/dev/pci/vga_pci.c
@@ -126,6 +126,13 @@ vga_pci_is_boot_display(device_t dev)
if ((config & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN)) == 0)
return (0);
+ /*
+ * Disable interrupts until a chipset driver is loaded for
+ * this PCI device. Else unhandled display adapter interrupts
+ * might freeze the CPU.
+ */
+ pci_write_config(dev, PCIR_COMMAND, config | PCIM_CMD_INTxDIS, 2);
+
/* This video card is the boot display: record its unit number. */
vga_pci_default_unit = unit;
device_set_flags(dev, 1);
diff --git a/sys/dev/proto/proto.h b/sys/dev/proto/proto.h
index db61da548654..690d71fff85a 100644
--- a/sys/dev/proto/proto.h
+++ b/sys/dev/proto/proto.h
@@ -33,11 +33,15 @@
#define PROTO_RES_UNUSED 0
#define PROTO_RES_PCICFG 10
+#define PROTO_RES_BUSDMA 11
struct proto_res {
int r_type;
int r_rid;
- struct resource *r_res;
+ union {
+ struct resource *res;
+ void *busdma;
+ } r_d;
u_long r_size;
union {
void *cookie;
diff --git a/sys/dev/proto/proto_bus_pci.c b/sys/dev/proto/proto_bus_pci.c
index 012469a2d712..53ebb5ee7db5 100644
--- a/sys/dev/proto/proto_bus_pci.c
+++ b/sys/dev/proto/proto_bus_pci.c
@@ -82,23 +82,27 @@ proto_pci_attach(device_t dev)
{
struct proto_softc *sc;
struct resource *res;
+ uint32_t val;
int bar, rid, type;
sc = device_get_softc(dev);
proto_add_resource(sc, PROTO_RES_PCICFG, 0, NULL);
+ proto_add_resource(sc, PROTO_RES_BUSDMA, 0, NULL);
for (bar = 0; bar < PCIR_MAX_BAR_0; bar++) {
rid = PCIR_BAR(bar);
- type = SYS_RES_MEMORY;
+ val = pci_read_config(dev, rid, 4);
+ type = (PCI_BAR_IO(val)) ? SYS_RES_IOPORT : SYS_RES_MEMORY;
res = bus_alloc_resource_any(dev, type, &rid, RF_ACTIVE);
- if (res == NULL) {
- type = SYS_RES_IOPORT;
- res = bus_alloc_resource_any(dev, type, &rid,
- RF_ACTIVE);
- }
- if (res != NULL)
- proto_add_resource(sc, type, rid, res);
+ if (res == NULL)
+ continue;
+ proto_add_resource(sc, type, rid, res);
+ if (type == SYS_RES_IOPORT)
+ continue;
+ /* Skip over adjacent BAR for 64-bit memory BARs. */
+ if ((val & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64)
+ bar++;
}
rid = 0;
diff --git a/sys/dev/proto/proto_busdma.c b/sys/dev/proto/proto_busdma.c
new file mode 100644
index 000000000000..e01e76fb9730
--- /dev/null
+++ b/sys/dev/proto/proto_busdma.c
@@ -0,0 +1,301 @@
+/*-
+ * Copyright (c) 2015 Marcel Moolenaar
+ * 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 ``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 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <machine/bus.h>
+#include <machine/bus_dma.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/rman.h>
+#include <sys/sbuf.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <dev/proto/proto.h>
+#include <dev/proto/proto_dev.h>
+#include <dev/proto/proto_busdma.h>
+
+MALLOC_DEFINE(M_PROTO_BUSDMA, "proto_busdma", "DMA management data");
+
+static int
+proto_busdma_tag_create(struct proto_busdma *busdma, struct proto_tag *parent,
+ struct proto_ioc_busdma *ioc)
+{
+ struct proto_tag *tag;
+
+ /*
+ * If nsegs is 1, ignore maxsegsz. What this means is that if we have
+ * just 1 segment, then maxsz should be equal to maxsegsz. To keep it
+ * simple for us, limit maxsegsz to maxsz in any case.
+ */
+ if (ioc->u.tag.maxsegsz > ioc->u.tag.maxsz || ioc->u.tag.nsegs == 1)
+ ioc->u.tag.maxsegsz = ioc->u.tag.maxsz;
+
+ /* A bndry of 0 really means ~0, or no boundary. */
+ if (ioc->u.tag.bndry == 0)
+ ioc->u.tag.bndry = ~0U;
+
+ tag = malloc(sizeof(*tag), M_PROTO_BUSDMA, M_WAITOK | M_ZERO);
+ if (parent != NULL) {
+ tag->parent = parent;
+ LIST_INSERT_HEAD(&parent->children, tag, peers);
+ tag->align = MAX(ioc->u.tag.align, parent->align);
+ tag->bndry = MIN(ioc->u.tag.bndry, parent->bndry);
+ tag->maxaddr = MIN(ioc->u.tag.maxaddr, parent->maxaddr);
+ tag->maxsz = MIN(ioc->u.tag.maxsz, parent->maxsz);
+ tag->maxsegsz = MIN(ioc->u.tag.maxsegsz, parent->maxsegsz);
+ tag->nsegs = MIN(ioc->u.tag.nsegs, parent->nsegs);
+ tag->datarate = MIN(ioc->u.tag.datarate, parent->datarate);
+ /* Write constraints back */
+ ioc->u.tag.align = tag->align;
+ ioc->u.tag.bndry = tag->bndry;
+ ioc->u.tag.maxaddr = tag->maxaddr;
+ ioc->u.tag.maxsz = tag->maxsz;
+ ioc->u.tag.maxsegsz = tag->maxsegsz;
+ ioc->u.tag.nsegs = tag->nsegs;
+ ioc->u.tag.datarate = tag->datarate;
+ } else {
+ tag->align = ioc->u.tag.align;
+ tag->bndry = ioc->u.tag.bndry;
+ tag->maxaddr = ioc->u.tag.maxaddr;
+ tag->maxsz = ioc->u.tag.maxsz;
+ tag->maxsegsz = ioc->u.tag.maxsegsz;
+ tag->nsegs = ioc->u.tag.nsegs;
+ tag->datarate = ioc->u.tag.datarate;
+ }
+ LIST_INSERT_HEAD(&busdma->tags, tag, tags);
+ ioc->result = (uintptr_t)(void *)tag;
+ return (0);
+}
+
+static int
+proto_busdma_tag_destroy(struct proto_busdma *busdma, struct proto_tag *tag)
+{
+
+ if (!LIST_EMPTY(&tag->mds))
+ return (EBUSY);
+ if (!LIST_EMPTY(&tag->children))
+ return (EBUSY);
+
+ if (tag->parent != NULL) {
+ LIST_REMOVE(tag, peers);
+ tag->parent = NULL;
+ }
+ LIST_REMOVE(tag, tags);
+ free(tag, M_PROTO_BUSDMA);
+ return (0);
+}
+
+static struct proto_tag *
+proto_busdma_tag_lookup(struct proto_busdma *busdma, u_long key)
+{
+ struct proto_tag *tag;
+
+ LIST_FOREACH(tag, &busdma->tags, tags) {
+ if ((void *)tag == (void *)key)
+ return (tag);
+ }
+ return (NULL);
+}
+
+static void
+proto_busdma_mem_alloc_callback(void *arg, bus_dma_segment_t *segs, int nseg,
+ int error)
+{
+ struct proto_ioc_busdma *ioc = arg;
+
+ ioc->u.mem.bus_nsegs = nseg;
+ ioc->u.mem.bus_addr = segs[0].ds_addr;
+}
+
+static int
+proto_busdma_mem_alloc(struct proto_busdma *busdma, struct proto_tag *tag,
+ struct proto_ioc_busdma *ioc)
+{
+ struct proto_md *md;
+ int error;
+
+ md = malloc(sizeof(*md), M_PROTO_BUSDMA, M_WAITOK | M_ZERO);
+ md->tag = tag;
+
+ error = bus_dma_tag_create(busdma->bd_roottag, tag->align, tag->bndry,
+ tag->maxaddr, BUS_SPACE_MAXADDR, NULL, NULL, tag->maxsz,
+ tag->nsegs, tag->maxsegsz, 0, NULL, NULL, &md->bd_tag);
+ if (error) {
+ free(md, M_PROTO_BUSDMA);
+ return (error);
+ }
+ error = bus_dmamem_alloc(md->bd_tag, &md->virtaddr, 0, &md->bd_map);
+ if (error) {
+ bus_dma_tag_destroy(md->bd_tag);
+ free(md, M_PROTO_BUSDMA);
+ return (error);
+ }
+ md->physaddr = pmap_kextract((uintptr_t)(md->virtaddr));
+ error = bus_dmamap_load(md->bd_tag, md->bd_map, md->virtaddr,
+ tag->maxsz, proto_busdma_mem_alloc_callback, ioc, BUS_DMA_NOWAIT);
+ if (error) {
+ bus_dmamem_free(md->bd_tag, md->virtaddr, md->bd_map);
+ bus_dma_tag_destroy(md->bd_tag);
+ free(md, M_PROTO_BUSDMA);
+ return (error);
+ }
+ LIST_INSERT_HEAD(&tag->mds, md, peers);
+ LIST_INSERT_HEAD(&busdma->mds, md, mds);
+ ioc->u.mem.phys_nsegs = 1;
+ ioc->u.mem.phys_addr = md->physaddr;
+ ioc->result = (uintptr_t)(void *)md;
+ return (0);
+}
+
+static int
+proto_busdma_mem_free(struct proto_busdma *busdma, struct proto_md *md)
+{
+
+ LIST_REMOVE(md, mds);
+ LIST_REMOVE(md, peers);
+ bus_dmamem_free(md->bd_tag, md->virtaddr, md->bd_map);
+ bus_dma_tag_destroy(md->bd_tag);
+ free(md, M_PROTO_BUSDMA);
+ return (0);
+}
+
+static struct proto_md *
+proto_busdma_md_lookup(struct proto_busdma *busdma, u_long key)
+{
+ struct proto_md *md;
+
+ LIST_FOREACH(md, &busdma->mds, mds) {
+ if ((void *)md == (void *)key)
+ return (md);
+ }
+ return (NULL);
+}
+
+struct proto_busdma *
+proto_busdma_attach(struct proto_softc *sc)
+{
+ struct proto_busdma *busdma;
+
+ busdma = malloc(sizeof(*busdma), M_PROTO_BUSDMA, M_WAITOK | M_ZERO);
+ return (busdma);
+}
+
+int
+proto_busdma_detach(struct proto_softc *sc, struct proto_busdma *busdma)
+{
+
+ proto_busdma_cleanup(sc, busdma);
+ free(busdma, M_PROTO_BUSDMA);
+ return (0);
+}
+
+int
+proto_busdma_cleanup(struct proto_softc *sc, struct proto_busdma *busdma)
+{
+ struct proto_md *md, *md1;
+ struct proto_tag *tag, *tag1;
+
+ LIST_FOREACH_SAFE(md, &busdma->mds, mds, md1)
+ proto_busdma_mem_free(busdma, md);
+ LIST_FOREACH_SAFE(tag, &busdma->tags, tags, tag1)
+ proto_busdma_tag_destroy(busdma, tag);
+ return (0);
+}
+
+int
+proto_busdma_ioctl(struct proto_softc *sc, struct proto_busdma *busdma,
+ struct proto_ioc_busdma *ioc)
+{
+ struct proto_tag *tag;
+ struct proto_md *md;
+ int error;
+
+ error = 0;
+ switch (ioc->request) {
+ case PROTO_IOC_BUSDMA_TAG_CREATE:
+ busdma->bd_roottag = bus_get_dma_tag(sc->sc_dev);
+ error = proto_busdma_tag_create(busdma, NULL, ioc);
+ break;
+ case PROTO_IOC_BUSDMA_TAG_DERIVE:
+ tag = proto_busdma_tag_lookup(busdma, ioc->key);
+ if (tag == NULL) {
+ error = EINVAL;
+ break;
+ }
+ error = proto_busdma_tag_create(busdma, tag, ioc);
+ break;
+ case PROTO_IOC_BUSDMA_TAG_DESTROY:
+ tag = proto_busdma_tag_lookup(busdma, ioc->key);
+ if (tag == NULL) {
+ error = EINVAL;
+ break;
+ }
+ error = proto_busdma_tag_destroy(busdma, tag);
+ break;
+ case PROTO_IOC_BUSDMA_MEM_ALLOC:
+ tag = proto_busdma_tag_lookup(busdma, ioc->u.mem.tag);
+ if (tag == NULL) {
+ error = EINVAL;
+ break;
+ }
+ error = proto_busdma_mem_alloc(busdma, tag, ioc);
+ break;
+ case PROTO_IOC_BUSDMA_MEM_FREE:
+ md = proto_busdma_md_lookup(busdma, ioc->key);
+ if (md == NULL) {
+ error = EINVAL;
+ break;
+ }
+ error = proto_busdma_mem_free(busdma, md);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return (error);
+}
+
+int
+proto_busdma_mmap_allowed(struct proto_busdma *busdma, vm_paddr_t physaddr)
+{
+ struct proto_md *md;
+
+ LIST_FOREACH(md, &busdma->mds, mds) {
+ if (physaddr >= trunc_page(md->physaddr) &&
+ physaddr <= trunc_page(md->physaddr + md->tag->maxsz))
+ return (1);
+ }
+ return (0);
+}
diff --git a/sys/dev/proto/proto_busdma.h b/sys/dev/proto/proto_busdma.h
new file mode 100644
index 000000000000..b4957f58531e
--- /dev/null
+++ b/sys/dev/proto/proto_busdma.h
@@ -0,0 +1,75 @@
+/*-
+ * Copyright (c) 2015 Marcel Moolenaar
+ * 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 ``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 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$
+ */
+
+#ifndef _DEV_PROTO_BUSDMA_H_
+#define _DEV_PROTO_BUSDMA_H_
+
+struct proto_md;
+
+struct proto_tag {
+ LIST_ENTRY(proto_tag) tags;
+ struct proto_tag *parent;
+ LIST_ENTRY(proto_tag) peers;
+ LIST_HEAD(,proto_tag) children;
+ LIST_HEAD(,proto_md) mds;
+ bus_addr_t align;
+ bus_addr_t bndry;
+ bus_addr_t maxaddr;
+ bus_size_t maxsz;
+ bus_size_t maxsegsz;
+ u_int nsegs;
+ u_int datarate;
+};
+
+struct proto_md {
+ LIST_ENTRY(proto_md) mds;
+ LIST_ENTRY(proto_md) peers;
+ struct proto_tag *tag;
+ void *virtaddr;
+ vm_paddr_t physaddr;
+ bus_dma_tag_t bd_tag;
+ bus_dmamap_t bd_map;
+};
+
+struct proto_busdma {
+ LIST_HEAD(,proto_tag) tags;
+ LIST_HEAD(,proto_md) mds;
+ bus_dma_tag_t bd_roottag;
+};
+
+struct proto_busdma *proto_busdma_attach(struct proto_softc *);
+int proto_busdma_detach(struct proto_softc *, struct proto_busdma *);
+
+int proto_busdma_cleanup(struct proto_softc *, struct proto_busdma *);
+
+int proto_busdma_ioctl(struct proto_softc *, struct proto_busdma *,
+ struct proto_ioc_busdma *);
+
+int proto_busdma_mmap_allowed(struct proto_busdma *, vm_paddr_t);
+
+#endif /* _DEV_PROTO_BUSDMA_H_ */
diff --git a/sys/dev/proto/proto_core.c b/sys/dev/proto/proto_core.c
index 5ea0a6c12667..86f08eb2e9d8 100644
--- a/sys/dev/proto/proto_core.c
+++ b/sys/dev/proto/proto_core.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <dev/proto/proto.h>
#include <dev/proto/proto_dev.h>
+#include <dev/proto/proto_busdma.h>
CTASSERT(SYS_RES_IRQ != PROTO_RES_UNUSED &&
SYS_RES_MEMORY != PROTO_RES_UNUSED &&
@@ -58,6 +59,9 @@ CTASSERT(SYS_RES_IRQ != PROTO_RES_UNUSED &&
CTASSERT(SYS_RES_IRQ != PROTO_RES_PCICFG &&
SYS_RES_MEMORY != PROTO_RES_PCICFG &&
SYS_RES_IOPORT != PROTO_RES_PCICFG);
+CTASSERT(SYS_RES_IRQ != PROTO_RES_BUSDMA &&
+ SYS_RES_MEMORY != PROTO_RES_BUSDMA &&
+ SYS_RES_IOPORT != PROTO_RES_BUSDMA);
devclass_t proto_devclass;
char proto_driver_name[] = "proto";
@@ -97,7 +101,7 @@ proto_add_resource(struct proto_softc *sc, int type, int rid,
r = sc->sc_res + sc->sc_rescnt++;
r->r_type = type;
r->r_rid = rid;
- r->r_res = res;
+ r->r_d.res = res;
return (0);
}
@@ -130,7 +134,7 @@ proto_attach(device_t dev)
break;
case SYS_RES_MEMORY:
case SYS_RES_IOPORT:
- r->r_size = rman_get_size(r->r_res);
+ r->r_size = rman_get_size(r->r_d.res);
r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
"proto/%s/%02x.%s", device_get_desc(dev), r->r_rid,
(r->r_type == SYS_RES_IOPORT) ? "io" : "mem");
@@ -144,6 +148,14 @@ proto_attach(device_t dev)
r->r_u.cdev->si_drv1 = sc;
r->r_u.cdev->si_drv2 = r;
break;
+ case PROTO_RES_BUSDMA:
+ r->r_d.busdma = proto_busdma_attach(sc);
+ r->r_size = 0; /* no read(2) nor write(2) */
+ r->r_u.cdev = make_dev(&proto_devsw, res, 0, 0, 0666,
+ "proto/%s/busdma", device_get_desc(dev));
+ r->r_u.cdev->si_drv1 = sc;
+ r->r_u.cdev->si_drv2 = r;
+ break;
}
}
return (0);
@@ -158,7 +170,7 @@ proto_detach(device_t dev)
sc = device_get_softc(dev);
- /* Don't detach if we have open device filess. */
+ /* Don't detach if we have open device files. */
for (res = 0; res < sc->sc_rescnt; res++) {
r = sc->sc_res + res;
if (r->r_opened)
@@ -170,17 +182,22 @@ proto_detach(device_t dev)
switch (r->r_type) {
case SYS_RES_IRQ:
/* XXX TODO */
+ bus_release_resource(dev, r->r_type, r->r_rid,
+ r->r_d.res);
break;
case SYS_RES_MEMORY:
case SYS_RES_IOPORT:
+ bus_release_resource(dev, r->r_type, r->r_rid,
+ r->r_d.res);
+ destroy_dev(r->r_u.cdev);
+ break;
case PROTO_RES_PCICFG:
destroy_dev(r->r_u.cdev);
break;
- }
- if (r->r_res != NULL) {
- bus_release_resource(dev, r->r_type, r->r_rid,
- r->r_res);
- r->r_res = NULL;
+ case PROTO_RES_BUSDMA:
+ proto_busdma_detach(sc, r->r_d.busdma);
+ destroy_dev(r->r_u.cdev);
+ break;
}
r->r_type = PROTO_RES_UNUSED;
}
@@ -207,10 +224,14 @@ static int
proto_close(struct cdev *cdev, int fflag, int devtype, struct thread *td)
{
struct proto_res *r;
+ struct proto_softc *sc;
+ sc = cdev->si_drv1;
r = cdev->si_drv2;
if (!atomic_cmpset_acq_ptr(&r->r_opened, (uintptr_t)td->td_proc, 0UL))
return (ENXIO);
+ if (r->r_type == PROTO_RES_BUSDMA)
+ proto_busdma_cleanup(sc, r->r_d.busdma);
return (0);
}
@@ -244,21 +265,21 @@ proto_read(struct cdev *cdev, struct uio *uio, int ioflag)
switch (width) {
case 1:
buf.x1[0] = (r->r_type == PROTO_RES_PCICFG) ?
- pci_read_config(dev, ofs, 1) : bus_read_1(r->r_res, ofs);
+ pci_read_config(dev, ofs, 1) : bus_read_1(r->r_d.res, ofs);
break;
case 2:
buf.x2[0] = (r->r_type == PROTO_RES_PCICFG) ?
- pci_read_config(dev, ofs, 2) : bus_read_2(r->r_res, ofs);
+ pci_read_config(dev, ofs, 2) : bus_read_2(r->r_d.res, ofs);
break;
case 4:
buf.x4[0] = (r->r_type == PROTO_RES_PCICFG) ?
- pci_read_config(dev, ofs, 4) : bus_read_4(r->r_res, ofs);
+ pci_read_config(dev, ofs, 4) : bus_read_4(r->r_d.res, ofs);
break;
#ifndef __i386__
case 8:
if (r->r_type == PROTO_RES_PCICFG)
return (EINVAL);
- buf.x8[0] = bus_read_8(r->r_res, ofs);
+ buf.x8[0] = bus_read_8(r->r_d.res, ofs);
break;
#endif
default:
@@ -305,25 +326,25 @@ proto_write(struct cdev *cdev, struct uio *uio, int ioflag)
if (r->r_type == PROTO_RES_PCICFG)
pci_write_config(dev, ofs, buf.x1[0], 1);
else
- bus_write_1(r->r_res, ofs, buf.x1[0]);
+ bus_write_1(r->r_d.res, ofs, buf.x1[0]);
break;
case 2:
if (r->r_type == PROTO_RES_PCICFG)
pci_write_config(dev, ofs, buf.x2[0], 2);
else
- bus_write_2(r->r_res, ofs, buf.x2[0]);
+ bus_write_2(r->r_d.res, ofs, buf.x2[0]);
break;
case 4:
if (r->r_type == PROTO_RES_PCICFG)
pci_write_config(dev, ofs, buf.x4[0], 4);
else
- bus_write_4(r->r_res, ofs, buf.x4[0]);
+ bus_write_4(r->r_d.res, ofs, buf.x4[0]);
break;
#ifndef __i386__
case 8:
if (r->r_type == PROTO_RES_PCICFG)
return (EINVAL);
- bus_write_8(r->r_res, ofs, buf.x8[0]);
+ bus_write_8(r->r_d.res, ofs, buf.x8[0]);
break;
#endif
default:
@@ -338,20 +359,35 @@ proto_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
struct thread *td)
{
struct proto_ioc_region *region;
+ struct proto_ioc_busdma *busdma;
struct proto_res *r;
+ struct proto_softc *sc;
int error;
+ sc = cdev->si_drv1;
r = cdev->si_drv2;
error = 0;
switch (cmd) {
case PROTO_IOC_REGION:
+ if (r->r_type == PROTO_RES_BUSDMA) {
+ error = EINVAL;
+ break;
+ }
region = (struct proto_ioc_region *)data;
region->size = r->r_size;
if (r->r_type == PROTO_RES_PCICFG)
region->address = 0;
else
- region->address = rman_get_start(r->r_res);
+ region->address = rman_get_start(r->r_d.res);
+ break;
+ case PROTO_IOC_BUSDMA:
+ if (r->r_type != PROTO_RES_BUSDMA) {
+ error = EINVAL;
+ break;
+ }
+ busdma = (struct proto_ioc_busdma *)data;
+ error = proto_busdma_ioctl(sc, r->r_d.busdma, busdma);
break;
default:
error = ENOIOCTL;
@@ -366,19 +402,29 @@ proto_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
{
struct proto_res *r;
- r = cdev->si_drv2;
-
- if (r->r_type != SYS_RES_MEMORY)
- return (ENXIO);
if (offset & PAGE_MASK)
return (EINVAL);
if (prot & PROT_EXEC)
return (EACCES);
- if (offset >= r->r_size)
- return (EINVAL);
- *paddr = rman_get_start(r->r_res) + offset;
+
+ r = cdev->si_drv2;
+
+ switch (r->r_type) {
+ case SYS_RES_MEMORY:
+ if (offset >= r->r_size)
+ return (EINVAL);
+ *paddr = rman_get_start(r->r_d.res) + offset;
#ifndef __sparc64__
- *memattr = VM_MEMATTR_UNCACHEABLE;
+ *memattr = VM_MEMATTR_UNCACHEABLE;
#endif
+ break;
+ case PROTO_RES_BUSDMA:
+ if (!proto_busdma_mmap_allowed(r->r_d.busdma, offset))
+ return (EINVAL);
+ *paddr = offset;
+ break;
+ default:
+ return (ENXIO);
+ }
return (0);
}
diff --git a/sys/dev/proto/proto_dev.h b/sys/dev/proto/proto_dev.h
index 0ea37495ce3b..88a61a71dac3 100644
--- a/sys/dev/proto/proto_dev.h
+++ b/sys/dev/proto/proto_dev.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014 Marcel Moolenaar
+ * Copyright (c) 2014, 2015 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,4 +40,37 @@ struct proto_ioc_region {
#define PROTO_IOC_REGION _IOWR(PROTO_IOC_CLASS, 1, struct proto_ioc_region)
+struct proto_ioc_busdma {
+ unsigned int request;
+#define PROTO_IOC_BUSDMA_TAG_CREATE 1
+#define PROTO_IOC_BUSDMA_TAG_DERIVE 2
+#define PROTO_IOC_BUSDMA_TAG_DESTROY 3
+#define PROTO_IOC_BUSDMA_MEM_ALLOC 10
+#define PROTO_IOC_BUSDMA_MEM_FREE 11
+ unsigned long key;
+ union {
+ struct {
+ unsigned long align;
+ unsigned long bndry;
+ unsigned long maxaddr;
+ unsigned long maxsz;
+ unsigned long maxsegsz;
+ unsigned int nsegs;
+ unsigned int datarate;
+ unsigned int flags;
+ } tag;
+ struct {
+ unsigned long tag;
+ unsigned int flags;
+ unsigned int phys_nsegs;
+ unsigned long phys_addr;
+ unsigned long bus_addr;
+ unsigned int bus_nsegs;
+ } mem;
+ } u;
+ unsigned long result;
+};
+
+#define PROTO_IOC_BUSDMA _IOWR(PROTO_IOC_CLASS, 2, struct proto_ioc_busdma)
+
#endif /* _DEV_PROTO_H_ */
diff --git a/sys/dev/psci/psci.c b/sys/dev/psci/psci.c
index 67f700a89b5a..4554fa6cd0fd 100644
--- a/sys/dev/psci/psci.c
+++ b/sys/dev/psci/psci.c
@@ -102,6 +102,24 @@ EARLY_DRIVER_MODULE(psci, simplebus, psci_driver, psci_devclass, 0, 0,
EARLY_DRIVER_MODULE(psci, ofwbus, psci_driver, psci_devclass, 0, 0,
BUS_PASS_CPU + BUS_PASS_ORDER_FIRST);
+static psci_callfn_t
+psci_get_callfn(phandle_t node)
+{
+ char method[16];
+
+ if ((OF_getprop(node, "method", method, sizeof(method))) > 0) {
+ if (strcmp(method, "hvc") == 0)
+ return (psci_hvc_despatch);
+ else if (strcmp(method, "smc") == 0)
+ return (psci_smc_despatch);
+ else
+ printf("psci: PSCI conduit \"%s\" invalid\n", method);
+ } else
+ printf("psci: PSCI conduit not supplied in the device tree\n");
+
+ return (NULL);
+}
+
static int
psci_probe(device_t dev)
{
@@ -126,7 +144,6 @@ psci_attach(device_t dev)
const struct ofw_compat_data *ocd;
psci_initfn_t psci_init;
phandle_t node;
- char method[16];
if (psci_softc != NULL)
return (ENXIO);
@@ -136,22 +153,9 @@ psci_attach(device_t dev)
KASSERT(psci_init != NULL, ("PSCI init function cannot be NULL"));
node = ofw_bus_get_node(dev);
- if ((OF_getprop(node, "method", method, sizeof(method))) > 0) {
- if (strcmp(method, "hvc") == 0)
- sc->psci_call = psci_hvc_despatch;
- else if (strcmp(method, "smc") == 0)
- sc->psci_call = psci_smc_despatch;
- else {
- device_printf(dev,
- "psci_attach: PSCI conduit \"%s\" invalid\n",
- method);
- return (ENXIO);
- }
- } else {
- device_printf(dev,
- "psci_attach: PSCI conduit not supplied in the DT\n");
+ sc->psci_call = psci_get_callfn(node);
+ if (sc->psci_call == NULL)
return (ENXIO);
- }
if (psci_init(dev))
return (ENXIO);
@@ -177,10 +181,27 @@ psci_get_version(struct psci_softc *sc)
int
psci_cpu_on(unsigned long cpu, unsigned long entry, unsigned long context_id)
{
+ psci_callfn_t callfn;
+ phandle_t node;
+ uint32_t fnid;
+
+ if (psci_softc == NULL) {
+ node = ofw_bus_find_compatible(OF_peer(0), "arm,psci-0.2");
+ if (node == 0)
+ /* TODO: Handle psci 0.1 */
+ return (PSCI_RETVAL_INTERNAL_FAILURE);
+
+ fnid = PSCI_FNID_CPU_ON;
+ callfn = psci_get_callfn(node);
+ if (callfn == NULL)
+ return (PSCI_RETVAL_INTERNAL_FAILURE);
+ } else {
+ callfn = psci_softc->psci_call;
+ fnid = psci_softc->psci_fnids[PSCI_FN_CPU_ON];
+ }
/* PSCI v0.1 and v0.2 both support cpu_on. */
- return(psci_softc->psci_call(psci_softc->psci_fnids[PSCI_FN_CPU_ON], cpu,
- entry, context_id));
+ return (callfn(fnid, cpu, entry, context_id));
}
static void
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c
index 02c93103245b..29ce8cbf8014 100644
--- a/sys/dev/ral/rt2560.c
+++ b/sys/dev/ral/rt2560.c
@@ -144,14 +144,14 @@ static void rt2560_disable_rf_tune(struct rt2560_softc *);
static void rt2560_enable_tsf_sync(struct rt2560_softc *);
static void rt2560_enable_tsf(struct rt2560_softc *);
static void rt2560_update_plcp(struct rt2560_softc *);
-static void rt2560_update_slot(struct ifnet *);
+static void rt2560_update_slot(struct ieee80211com *);
static void rt2560_set_basicrates(struct rt2560_softc *,
const struct ieee80211_rateset *);
static void rt2560_update_led(struct rt2560_softc *, int, int);
static void rt2560_set_bssid(struct rt2560_softc *, const uint8_t *);
static void rt2560_set_macaddr(struct rt2560_softc *, uint8_t *);
static void rt2560_get_macaddr(struct rt2560_softc *, uint8_t *);
-static void rt2560_update_promisc(struct ifnet *);
+static void rt2560_update_promisc(struct ieee80211com *);
static const char *rt2560_get_rf(int);
static void rt2560_read_config(struct rt2560_softc *);
static int rt2560_bbp_init(struct rt2560_softc *);
@@ -273,6 +273,8 @@ rt2560_attach(device_t dev, int id)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -1996,7 +1998,7 @@ rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
rt2560_init_locked(sc);
startall = 1;
} else
- rt2560_update_promisc(ifp);
+ rt2560_update_promisc(ic);
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
rt2560_stop_locked(sc);
@@ -2305,10 +2307,9 @@ rt2560_update_plcp(struct rt2560_softc *sc)
* IEEE Std 802.11-1999 pp. 85 to know how these values are computed.
*/
static void
-rt2560_update_slot(struct ifnet *ifp)
+rt2560_update_slot(struct ieee80211com *ic)
{
- struct rt2560_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct rt2560_softc *sc = ic->ic_softc;
uint8_t slottime;
uint16_t tx_sifs, tx_pifs, tx_difs, eifs;
uint32_t tmp;
@@ -2435,21 +2436,21 @@ rt2560_get_macaddr(struct rt2560_softc *sc, uint8_t *addr)
}
static void
-rt2560_update_promisc(struct ifnet *ifp)
+rt2560_update_promisc(struct ieee80211com *ic)
{
- struct rt2560_softc *sc = ifp->if_softc;
+ struct rt2560_softc *sc = ic->ic_softc;
uint32_t tmp;
tmp = RAL_READ(sc, RT2560_RXCSR0);
tmp &= ~RT2560_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
tmp |= RT2560_DROP_NOT_TO_ME;
RAL_WRITE(sc, RT2560_RXCSR0, tmp);
- DPRINTF(sc, "%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
- "entering" : "leaving");
+ DPRINTF(sc, "%s promiscuous mode\n",
+ (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
}
static const char *
@@ -2658,7 +2659,7 @@ rt2560_init_locked(struct rt2560_softc *sc)
/* set basic rate set (will be updated later) */
RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x153);
- rt2560_update_slot(ifp);
+ rt2560_update_slot(ic);
rt2560_update_plcp(sc);
rt2560_update_led(sc, 0, 0);
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index 448ba5746bd2..15a2364a2c74 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -147,9 +147,9 @@ static void rt2661_set_bssid(struct rt2661_softc *,
const uint8_t *);
static void rt2661_set_macaddr(struct rt2661_softc *,
const uint8_t *);
-static void rt2661_update_promisc(struct ifnet *);
+static void rt2661_update_promisc(struct ieee80211com *);
static int rt2661_wme_update(struct ieee80211com *) __unused;
-static void rt2661_update_slot(struct ifnet *);
+static void rt2661_update_slot(struct ieee80211com *);
static const char *rt2661_get_rf(int);
static void rt2661_read_eeprom(struct rt2661_softc *,
uint8_t macaddr[IEEE80211_ADDR_LEN]);
@@ -274,6 +274,8 @@ rt2661_attach(device_t dev, int id)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -1734,7 +1736,7 @@ rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
rt2661_init_locked(sc);
startall = 1;
} else
- rt2661_update_promisc(ifp);
+ rt2661_update_promisc(ic);
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
rt2661_stop_locked(sc);
@@ -2078,21 +2080,21 @@ rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr)
}
static void
-rt2661_update_promisc(struct ifnet *ifp)
+rt2661_update_promisc(struct ieee80211com *ic)
{
- struct rt2661_softc *sc = ifp->if_softc;
+ struct rt2661_softc *sc = ic->ic_softc;
uint32_t tmp;
tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
tmp &= ~RT2661_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
tmp |= RT2661_DROP_NOT_TO_ME;
RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
- DPRINTF(sc, "%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
- "entering" : "leaving");
+ DPRINTF(sc, "%s promiscuous mode\n",
+ (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
}
/*
@@ -2142,10 +2144,9 @@ rt2661_wme_update(struct ieee80211com *ic)
}
static void
-rt2661_update_slot(struct ifnet *ifp)
+rt2661_update_slot(struct ieee80211com *ic)
{
- struct rt2661_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct rt2661_softc *sc = ic->ic_softc;
uint8_t slottime;
uint32_t tmp;
diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c
index b29a0eb60aaf..782fa1f9780b 100644
--- a/sys/dev/ral/rt2860.c
+++ b/sys/dev/ral/rt2860.c
@@ -154,8 +154,8 @@ static void rt2860_set_leds(struct rt2860_softc *, uint16_t);
static void rt2860_set_gp_timer(struct rt2860_softc *, int);
static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *);
static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *);
-static void rt2860_update_promisc(struct ifnet *);
-static void rt2860_updateslot(struct ifnet *);
+static void rt2860_update_promisc(struct ieee80211com *);
+static void rt2860_updateslot(struct ieee80211com *);
static void rt2860_updateprot(struct ifnet *);
static int rt2860_updateedca(struct ieee80211com *);
#ifdef HW_CRYPTO
@@ -315,6 +315,8 @@ rt2860_attach(device_t dev, int id)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -2051,7 +2053,7 @@ rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
rt2860_init_locked(sc);
startall = 1;
} else
- rt2860_update_promisc(ifp);
+ rt2860_update_promisc(ic);
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
rt2860_stop_locked(sc);
@@ -3099,10 +3101,9 @@ rt2860_set_macaddr(struct rt2860_softc *sc, const uint8_t *addr)
}
static void
-rt2860_updateslot(struct ifnet *ifp)
+rt2860_updateslot(struct ieee80211com *ic)
{
- struct rt2860_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct rt2860_softc *sc = ic->ic_softc;
uint32_t tmp;
tmp = RAL_READ(sc, RT2860_BKOFF_SLOT_CFG);
@@ -3137,14 +3138,14 @@ rt2860_updateprot(struct ifnet *ifp)
}
static void
-rt2860_update_promisc(struct ifnet *ifp)
+rt2860_update_promisc(struct ieee80211com *ic)
{
- struct rt2860_softc *sc = ifp->if_softc;
+ struct rt2860_softc *sc = ic->ic_softc;
uint32_t tmp;
tmp = RAL_READ(sc, RT2860_RX_FILTR_CFG);
tmp &= ~RT2860_DROP_NOT_MYBSS;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
tmp |= RT2860_DROP_NOT_MYBSS;
RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp);
}
diff --git a/sys/dev/sfxge/common/ef10_tlv_layout.h b/sys/dev/sfxge/common/ef10_tlv_layout.h
new file mode 100644
index 000000000000..e413a5d8c70b
--- /dev/null
+++ b/sys/dev/sfxge/common/ef10_tlv_layout.h
@@ -0,0 +1,691 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ *
+ * $FreeBSD$
+ */
+
+/* These structures define the layouts for the TLV items stored in static and
+ * dynamic configuration partitions in NVRAM for EF10 (Huntington etc.).
+ *
+ * They contain the same sort of information that was kept in the
+ * siena_mc_static_config_hdr_t and siena_mc_dynamic_config_hdr_t structures
+ * (defined in <ci/mgmt/mc_flash_layout.h> and <ci/mgmt/mc_dynamic_cfg.h>) for
+ * Siena.
+ *
+ * These are used directly by the MC and should also be usable directly on host
+ * systems which are little-endian and do not do strange things with structure
+ * padding. (Big-endian host systems will require some byte-swapping.)
+ *
+ * -----
+ *
+ * Please refer to SF-108797-SW for a general overview of the TLV partition
+ * format.
+ *
+ * -----
+ *
+ * The current tag IDs have a general structure: with the exception of the
+ * special values defined in the document, they are of the form 0xLTTTNNNN,
+ * where:
+ *
+ * - L is a location, indicating where this tag is expected to be found:
+ * 0 for static configuration, or 1 for dynamic configuration. Other
+ * values are reserved.
+ *
+ * - TTT is a type, which is just a unique value. The same type value
+ * might appear in both locations, indicating a relationship between
+ * the items (e.g. static and dynamic VPD below).
+ *
+ * - NNNN is an index of some form. Some item types are per-port, some
+ * are per-PF, some are per-partition-type.
+ *
+ * -----
+ *
+ * As with the previous Siena structures, each structure here is laid out
+ * carefully: values are aligned to their natural boundary, with explicit
+ * padding fields added where necessary. (No, technically this does not
+ * absolutely guarantee portability. But, in practice, compilers are generally
+ * sensible enough not to introduce completely pointless padding, and it works
+ * well enough.)
+ */
+
+
+#ifndef CI_MGMT_TLV_LAYOUT_H
+#define CI_MGMT_TLV_LAYOUT_H
+
+
+/* ----------------------------------------------------------------------------
+ * General structure (defined by SF-108797-SW)
+ * ----------------------------------------------------------------------------
+ */
+
+
+/* The "end" tag.
+ *
+ * (Note that this is *not* followed by length or value fields: anything after
+ * the tag itself is irrelevant.)
+ */
+
+#define TLV_TAG_END (0xEEEEEEEE)
+
+
+/* Other special reserved tag values.
+ */
+
+#define TLV_TAG_SKIP (0x00000000)
+#define TLV_TAG_INVALID (0xFFFFFFFF)
+
+
+/* TLV partition header.
+ *
+ * In a TLV partition, this must be the first item in the sequence, at offset
+ * 0.
+ */
+
+#define TLV_TAG_PARTITION_HEADER (0xEF10DA7A)
+
+struct tlv_partition_header {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t type_id;
+ uint16_t reserved;
+ uint32_t generation;
+ uint32_t total_length;
+};
+
+
+/* TLV partition trailer.
+ *
+ * In a TLV partition, this must be the last item in the sequence, immediately
+ * preceding the TLV_TAG_END word.
+ */
+
+#define TLV_TAG_PARTITION_TRAILER (0xEF101A57)
+
+struct tlv_partition_trailer {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t generation;
+ uint32_t checksum;
+};
+
+
+/* Appendable TLV partition header.
+ *
+ * In an appendable TLV partition, this must be the first item in the sequence,
+ * at offset 0. (Note that, unlike the configuration partitions, there is no
+ * trailer before the TLV_TAG_END word.)
+ */
+
+#define TLV_TAG_APPENDABLE_PARTITION_HEADER (0xEF10ADA7)
+
+struct tlv_appendable_partition_header {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t type_id;
+ uint16_t reserved;
+};
+
+
+/* ----------------------------------------------------------------------------
+ * Configuration items
+ * ----------------------------------------------------------------------------
+ */
+
+
+/* NIC global capabilities.
+ */
+
+#define TLV_TAG_GLOBAL_CAPABILITIES (0x00010000)
+
+struct tlv_global_capabilities {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t flags;
+};
+
+
+/* Siena-style per-port MAC address allocation.
+ *
+ * There are <count> addresses, starting at <base_address> and incrementing
+ * by adding <stride> to the low-order byte(s).
+ *
+ * (See also TLV_TAG_GLOBAL_MAC for an alternative, specifying a global pool
+ * of contiguous MAC addresses for the firmware to allocate as it sees fit.)
+ */
+
+#define TLV_TAG_PORT_MAC(port) (0x00020000 + (port))
+
+struct tlv_port_mac {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t base_address[6];
+ uint16_t reserved;
+ uint16_t count;
+ uint16_t stride;
+};
+
+
+/* Static VPD.
+ *
+ * This is the portion of VPD which is set at manufacturing time and not
+ * expected to change. It is formatted as a standard PCI VPD block.
+ */
+
+#define TLV_TAG_PF_STATIC_VPD(pf) (0x00030000 + (pf))
+
+struct tlv_pf_static_vpd {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t bytes[];
+};
+
+
+/* Dynamic VPD.
+ *
+ * This is the portion of VPD which may be changed (e.g. by firmware updates).
+ * It is formatted as a standard PCI VPD block.
+ */
+
+#define TLV_TAG_PF_DYNAMIC_VPD(pf) (0x10030000 + (pf))
+
+struct tlv_pf_dynamic_vpd {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t bytes[];
+};
+
+
+/* "DBI" PCI config space changes.
+ *
+ * This is a set of edits made to the default PCI config space values before
+ * the device is allowed to enumerate.
+ */
+
+#define TLV_TAG_PF_DBI(pf) (0x00040000 + (pf))
+
+struct tlv_pf_dbi {
+ uint32_t tag;
+ uint32_t length;
+ struct {
+ uint16_t addr;
+ uint16_t byte_enables;
+ uint32_t value;
+ } items[];
+};
+
+
+/* Partition subtype codes.
+ *
+ * A subtype may optionally be stored for each type of partition present in
+ * the NVRAM. For example, this may be used to allow a generic firmware update
+ * utility to select a specific variant of firmware for a specific variant of
+ * board.
+ *
+ * The description[] field is an optional string which is returned in the
+ * MC_CMD_NVRAM_METADATA response if present.
+ */
+
+#define TLV_TAG_PARTITION_SUBTYPE(type) (0x00050000 + (type))
+
+struct tlv_partition_subtype {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t subtype;
+ uint8_t description[];
+};
+
+
+/* Partition version codes.
+ *
+ * A version may optionally be stored for each type of partition present in
+ * the NVRAM. This provides a standard way of tracking the currently stored
+ * version of each of the various component images.
+ */
+
+#define TLV_TAG_PARTITION_VERSION(type) (0x10060000 + (type))
+
+struct tlv_partition_version {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t version_w;
+ uint16_t version_x;
+ uint16_t version_y;
+ uint16_t version_z;
+};
+
+/* Global PCIe configuration */
+
+#define TLV_TAG_GLOBAL_PCIE_CONFIG (0x10070000)
+
+struct tlv_pcie_config {
+ uint32_t tag;
+ uint32_t length;
+ int16_t max_pf_number; /**< Largest PF RID (lower PFs may be hidden) */
+ uint16_t pf_aper; /**< BIU aperture for PF BAR2 */
+ uint16_t vf_aper; /**< BIU aperture for VF BAR0 */
+ uint16_t int_aper; /**< BIU aperture for PF BAR4 and VF BAR2 */
+#define TLV_MAX_PF_DEFAULT (-1) /* Use FW default for largest PF RID */
+#define TLV_APER_DEFAULT (0xFFFF) /* Use FW default for a given aperture */
+};
+
+/* Per-PF configuration. Note that not all these fields are necessarily useful
+ * as the apertures are constrained by the BIU settings (the one case we do
+ * use is to make BAR2 bigger than the BIU thinks to reserve space), but we can
+ * tidy things up later */
+
+#define TLV_TAG_PF_PCIE_CONFIG(pf) (0x10080000 + (pf))
+
+struct tlv_per_pf_pcie_config {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t vfs_total;
+ uint8_t port_allocation;
+ uint16_t vectors_per_pf;
+ uint16_t vectors_per_vf;
+ uint8_t pf_bar0_aperture;
+ uint8_t pf_bar2_aperture;
+ uint8_t vf_bar0_aperture;
+ uint8_t vf_base;
+ uint16_t supp_pagesz;
+ uint16_t msix_vec_base;
+};
+
+
+/* Development ONLY. This is a single TLV tag for all the gubbins
+ * that can be set through the MC command-line other than the PCIe
+ * settings. This is a temporary measure. */
+#define TLV_TAG_TMP_GUBBINS (0x10090000)
+
+struct tlv_tmp_gubbins {
+ uint32_t tag;
+ uint32_t length;
+ /* Consumed by dpcpu.c */
+ uint64_t tx0_tags; /* Bitmap */
+ uint64_t tx1_tags; /* Bitmap */
+ uint64_t dl_tags; /* Bitmap */
+ uint32_t flags;
+#define TLV_DPCPU_TX_STRIPE (1) /* TX striping is on */
+#define TLV_DPCPU_BIU_TAGS (2) /* Use BIU tag manager */
+#define TLV_DPCPU_TX0_TAGS (4) /* tx0_tags is valid */
+#define TLV_DPCPU_TX1_TAGS (8) /* tx1_tags is valid */
+#define TLV_DPCPU_DL_TAGS (16) /* dl_tags is valid */
+ /* Consumed by features.c */
+ uint32_t dut_features; /* All 1s -> leave alone */
+ int8_t with_rmon; /* 0 -> off, 1 -> on, -1 -> leave alone */
+ /* Consumed by clocks_hunt.c */
+ int8_t clk_mode; /* 0 -> off, 1 -> on, -1 -> leave alone */
+ /* Consumed by sram.c */
+ int8_t rx_dc_size; /* -1 -> leave alone */
+ int8_t tx_dc_size;
+ int16_t num_q_allocs;
+};
+
+/* Global port configuration
+ *
+ * This is now deprecated in favour of a platform-provided default
+ * and dynamic config override via tlv_global_port_options.
+ */
+#define TLV_TAG_GLOBAL_PORT_CONFIG (0x000a0000)
+
+struct tlv_global_port_config {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t ports_per_core;
+ uint32_t max_port_speed;
+};
+
+
+/* Firmware options.
+ *
+ * This is intended for user-configurable selection of optional firmware
+ * features and variants.
+ *
+ * Initially, this consists only of the satellite CPU firmware variant
+ * selection, but this tag could be extended in the future (using the
+ * tag length to determine whether additional fields are present).
+ */
+
+#define TLV_TAG_FIRMWARE_OPTIONS (0x100b0000)
+
+struct tlv_firmware_options {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t firmware_variant;
+#define TLV_FIRMWARE_VARIANT_DRIVER_SELECTED (0xffffffff)
+
+/* These are the values for overriding the driver's choice; the definitions
+ * are taken from MCDI so that they don't get out of step. Include
+ * <ci/mgmt/mc_driver_pcol.h> or the equivalent from your driver's tree if
+ * you need to use these constants.
+ */
+#define TLV_FIRMWARE_VARIANT_FULL_FEATURED MC_CMD_FW_FULL_FEATURED
+#define TLV_FIRMWARE_VARIANT_LOW_LATENCY MC_CMD_FW_LOW_LATENCY
+#define TLV_FIRMWARE_VARIANT_PACKED_STREAM MC_CMD_FW_PACKED_STREAM
+#define TLV_FIRMWARE_VARIANT_HIGH_TX_RATE MC_CMD_FW_HIGH_TX_RATE
+#define TLV_FIRMWARE_VARIANT_PACKED_STREAM_HASH_MODE_1 \
+ MC_CMD_FW_PACKED_STREAM_HASH_MODE_1
+};
+
+/* Voltage settings
+ *
+ * Intended for boards with A0 silicon where the core voltage may
+ * need tweaking. Most likely set once when the pass voltage is
+ * determined. */
+
+#define TLV_TAG_0V9_SETTINGS (0x000c0000)
+
+struct tlv_0v9_settings {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t flags; /* Boards with high 0v9 settings may need active cooling */
+#define TLV_TAG_0V9_REQUIRES_FAN (1)
+ uint16_t target_voltage; /* In millivolts */
+ /* Since the limits are meant to be centred to the target (and must at least
+ * contain it) they need setting as well. */
+ uint16_t warn_low; /* In millivolts */
+ uint16_t warn_high; /* In millivolts */
+ uint16_t panic_low; /* In millivolts */
+ uint16_t panic_high; /* In millivolts */
+};
+
+
+/* Clock configuration */
+
+#define TLV_TAG_CLOCK_CONFIG (0x000d0000)
+
+struct tlv_clock_config {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t clk_sys; /* MHz */
+ uint16_t clk_dpcpu; /* MHz */
+ uint16_t clk_icore; /* MHz */
+ uint16_t clk_pcs; /* MHz */
+};
+
+#define TLV_TAG_CLOCK_CONFIG_MEDFORD (0x00100000)
+
+struct tlv_clock_config_medford {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t clk_sys; /* MHz */
+ uint16_t clk_mc; /* MHz */
+ uint16_t clk_rmon; /* MHz */
+ uint16_t clk_vswitch; /* MHz */
+ uint16_t clk_dpcpu; /* MHz */
+ uint16_t clk_pcs; /* MHz */
+};
+
+
+/* EF10-style global pool of MAC addresses.
+ *
+ * There are <count> addresses, starting at <base_address>, which are
+ * contiguous. Firmware is responsible for allocating addresses from this
+ * pool to ports / PFs as appropriate.
+ */
+
+#define TLV_TAG_GLOBAL_MAC (0x000e0000)
+
+struct tlv_global_mac {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t base_address[6];
+ uint16_t reserved1;
+ uint16_t count;
+ uint16_t reserved2;
+};
+
+#define TLV_TAG_ATB_0V9_TARGET (0x000f0000)
+
+/* The target value for the 0v9 power rail measured on-chip at the
+ * analogue test bus */
+struct tlv_0v9_atb_target {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t millivolts;
+ uint16_t reserved;
+};
+
+/* Global PCIe configuration, second revision. This represents the visible PFs
+ * by a bitmap rather than having the number of the highest visible one. As such
+ * it can (for a 16-PF chip) represent a superset of what TLV_TAG_GLOBAL_PCIE_CONFIG
+ * can and it should be used in place of that tag in future (but compatibility with
+ * the old tag will be left in the firmware indefinitely). */
+
+#define TLV_TAG_GLOBAL_PCIE_CONFIG_R2 (0x10100000)
+
+struct tlv_pcie_config_r2 {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t visible_pfs; /**< Bitmap of visible PFs */
+ uint16_t pf_aper; /**< BIU aperture for PF BAR2 */
+ uint16_t vf_aper; /**< BIU aperture for VF BAR0 */
+ uint16_t int_aper; /**< BIU aperture for PF BAR4 and VF BAR2 */
+};
+
+/* Dynamic port mode.
+ *
+ * Allows selecting alternate port configuration for platforms that support it
+ * (e.g. 1x40G vs 2x10G on Milano, 1x40G vs 4x10G on Medford). This affects the
+ * number of externally visible ports (and, hence, PF to port mapping), so must
+ * be done at boot time.
+ *
+ * This tag supercedes tlv_global_port_config.
+ */
+
+#define TLV_TAG_GLOBAL_PORT_MODE (0x10110000)
+
+struct tlv_global_port_mode {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t port_mode;
+#define TLV_PORT_MODE_DEFAULT (0xffffffff) /* Default for given platform */
+#define TLV_PORT_MODE_10G (0) /* 10G, single SFP/10G-KR */
+#define TLV_PORT_MODE_40G (1) /* 40G, single QSFP/40G-KR */
+#define TLV_PORT_MODE_10G_10G (2) /* 2x10G, dual SFP/10G-KR or single QSFP */
+#define TLV_PORT_MODE_40G_40G (3) /* 40G + 40G, dual QSFP/40G-KR (Greenport, Medford) */
+#define TLV_PORT_MODE_10G_10G_10G_10G (4) /* 2x10G + 2x10G, quad SFP/10G-KR or dual QSFP (Greenport, Medford) */
+#define TLV_PORT_MODE_10G_10G_10G_10G_Q (5) /* 4x10G, single QSFP, cage 0 (Medford) */
+#define TLV_PORT_MODE_40G_10G_10G (6) /* 1x40G + 2x10G, dual QSFP (Greenport, Medford) */
+#define TLV_PORT_MODE_10G_10G_40G (7) /* 2x10G + 1x40G, dual QSFP (Greenport, Medford) */
+#define TLV_PORT_MODE_10G_10G_10G_10G_Q2 (8) /* 4x10G, single QSFP, cage 1 (Medford) */
+#define TLV_PORT_MODE_MAX TLV_PORT_MODE_10G_10G_10G_10G_Q2
+};
+
+/* Type of the v-switch created implicitly by the firmware */
+
+#define TLV_TAG_VSWITCH_TYPE(port) (0x10120000 + (port))
+
+struct tlv_vswitch_type {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t vswitch_type;
+#define TLV_VSWITCH_TYPE_DEFAULT (0xffffffff) /* Firmware default; equivalent to no TLV present for a given port */
+#define TLV_VSWITCH_TYPE_NONE (0)
+#define TLV_VSWITCH_TYPE_VLAN (1)
+#define TLV_VSWITCH_TYPE_VEB (2)
+#define TLV_VSWITCH_TYPE_VEPA (3)
+#define TLV_VSWITCH_TYPE_MUX (4)
+#define TLV_VSWITCH_TYPE_TEST (5)
+};
+
+/* A VLAN tag for the v-port created implicitly by the firmware */
+
+#define TLV_TAG_VPORT_VLAN_TAG(pf) (0x10130000 + (pf))
+
+struct tlv_vport_vlan_tag {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t vlan_tag;
+#define TLV_VPORT_NO_VLAN_TAG (0xFFFFFFFF) /* Default in the absence of TLV for a given PF */
+};
+
+/* Offset to be applied to the 0v9 setting, wherever it came from */
+
+#define TLV_TAG_ATB_0V9_OFFSET (0x10140000)
+
+struct tlv_0v9_atb_offset {
+ uint32_t tag;
+ uint32_t length;
+ int16_t offset_millivolts;
+ uint16_t reserved;
+};
+
+/* A privilege mask given on reset to all non-admin PCIe functions (that is other than first-PF-per-port).
+ * The meaning of particular bits is defined in mcdi_ef10.yml under MC_CMD_PRIVILEGE_MASK, see also bug 44583.
+ * TLV_TAG_PRIVILEGE_MASK_ADD specifies bits that should be added (ORed) to firmware default while
+ * TLV_TAG_PRIVILEGE_MASK_REM specifies bits that should be removed (ANDed) from firmware default:
+ * Initial_privilege_mask = (firmware_default_mask | privilege_mask_add) & ~privilege_mask_rem */
+
+#define TLV_TAG_PRIVILEGE_MASK (0x10150000) /* legacy symbol - do not use */
+
+struct tlv_privilege_mask { /* legacy structure - do not use */
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask;
+};
+
+#define TLV_TAG_PRIVILEGE_MASK_ADD (0x10150000)
+
+struct tlv_privilege_mask_add {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask_add;
+};
+
+#define TLV_TAG_PRIVILEGE_MASK_REM (0x10160000)
+
+struct tlv_privilege_mask_rem {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask_rem;
+};
+
+/* Additional privileges given to all PFs.
+ * This tag takes precedence over TLV_TAG_PRIVILEGE_MASK_REM. */
+
+#define TLV_TAG_PRIVILEGE_MASK_ADD_ALL_PFS (0x10190000)
+
+struct tlv_privilege_mask_add_all_pfs {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask_add;
+};
+
+/* Additional privileges given to a selected PF.
+ * This tag takes precedence over TLV_TAG_PRIVILEGE_MASK_REM. */
+
+#define TLV_TAG_PRIVILEGE_MASK_ADD_SINGLE_PF(pf) (0x101A0000 + (pf))
+
+struct tlv_privilege_mask_add_single_pf {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask_add;
+};
+
+/* Turning on/off the PFIOV mode.
+ * This tag only takes effect if TLV_TAG_VSWITCH_TYPE is missing or set to DEFAULT. */
+
+#define TLV_TAG_PFIOV(port) (0x10170000 + (port))
+
+struct tlv_pfiov {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t pfiov;
+#define TLV_PFIOV_OFF (0) /* Default */
+#define TLV_PFIOV_ON (1)
+};
+
+/* Multicast filter chaining mode selection.
+ *
+ * When enabled, multicast packets are delivered to all recipients of all
+ * matching multicast filters, with the exception that IP multicast filters
+ * will steal traffic from MAC multicast filters on a per-function basis.
+ * (New behaviour.)
+ *
+ * When disabled, multicast packets will always be delivered only to the
+ * recipients of the highest priority matching multicast filter.
+ * (Legacy behaviour.)
+ *
+ * The DEFAULT mode (which is the same as the tag not being present at all)
+ * is equivalent to ENABLED in production builds, and DISABLED in eftest
+ * builds.
+ *
+ * This option is intended to provide run-time control over this feature
+ * while it is being stabilised and may be withdrawn at some point in the
+ * future; the new behaviour is intended to become the standard behaviour.
+ */
+
+#define TLV_TAG_MCAST_FILTER_CHAINING (0x10180000)
+
+struct tlv_mcast_filter_chaining {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t mode;
+#define TLV_MCAST_FILTER_CHAINING_DEFAULT (0xffffffff)
+#define TLV_MCAST_FILTER_CHAINING_DISABLED (0)
+#define TLV_MCAST_FILTER_CHAINING_ENABLED (1)
+};
+
+
+/* Pacer rate limit per PF */
+#define TLV_TAG_RATE_LIMIT(pf) (0x101b0000 + (pf))
+
+struct tlv_rate_limit {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t rate_mbps;
+};
+
+
+/* OCSD Enable/Disable
+ *
+ * This setting allows OCSD to be disabled. This is a requirement for HP
+ * servers to support PCI passthrough for virtualization.
+ *
+ * The DEFAULT mode (which is the same as the tag not being present) is
+ * equivalent to ENABLED.
+ *
+ * This option is not used by the MCFW, and is entirely handled by the various
+ * drivers that support OCSD, by reading the setting before they attempt
+ * to enable OCSD.
+ *
+ * bit0: OCSD Disabled/Enabled
+ */
+
+#define TLV_TAG_OCSD (0x101C0000)
+
+struct tlv_ocsd {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t mode;
+#define TLV_OCSD_DISABLED 0
+#define TLV_OCSD_ENABLED 1 /* Default */
+};
+
+#endif /* CI_MGMT_TLV_LAYOUT_H */
diff --git a/sys/dev/sfxge/common/efsys.h b/sys/dev/sfxge/common/efsys.h
index d911c43c51fa..0a7b1ad6cd3f 100644
--- a/sys/dev/sfxge/common/efsys.h
+++ b/sys/dev/sfxge/common/efsys.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -56,6 +60,7 @@ extern "C" {
#else
#define EFSYS_USE_UINT64 0
#endif
+#define EFSYS_HAS_SSE2_M128 0
#if _BYTE_ORDER == _BIG_ENDIAN
#define EFSYS_IS_BIG_ENDIAN 1
#define EFSYS_IS_LITTLE_ENDIAN 0
@@ -90,6 +95,10 @@ extern "C" {
#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
#endif
+#ifndef P2ALIGN
+#define P2ALIGN(_x, _a) ((_x) & -(_a))
+#endif
+
#ifndef IS2P
#define ISP2(x) (((x) & ((x) - 1)) == 0)
#endif
@@ -176,7 +185,7 @@ prefetch_read_once(void *addr)
#endif
static __inline void
sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
- struct mbuf *m, bus_dma_segment_t *seg)
+ struct mbuf *m, bus_dma_segment_t *seg)
{
#if defined(__i386__) || defined(__amd64__)
seg->ds_addr = pmap_kextract(mtod(m, vm_offset_t));
@@ -188,10 +197,6 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#endif
}
-/* Modifiers used for DOS builds */
-#define __cs
-#define __far
-
/* Modifiers used for Windows builds */
#define __in
#define __in_opt
@@ -231,6 +236,7 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_FALCON 0
#define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE 0
#define EFSYS_OPT_SIENA 1
+#define EFSYS_OPT_HUNTINGTON 1
#ifdef DEBUG
#define EFSYS_OPT_CHECK_REG 1
#else
@@ -248,19 +254,19 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_MON_NULL 0
#define EFSYS_OPT_MON_LM87 0
#define EFSYS_OPT_MON_MAX6647 0
-#define EFSYS_OPT_MON_SIENA 0
+#define EFSYS_OPT_MON_MCDI 0
#define EFSYS_OPT_MON_STATS 0
#define EFSYS_OPT_PHY_NULL 0
#define EFSYS_OPT_PHY_QT2022C2 0
#define EFSYS_OPT_PHY_SFX7101 0
#define EFSYS_OPT_PHY_TXC43128 0
-#define EFSYS_OPT_PHY_PM8358 0
#define EFSYS_OPT_PHY_SFT9001 0
#define EFSYS_OPT_PHY_QT2025C 0
#define EFSYS_OPT_PHY_STATS 1
#define EFSYS_OPT_PHY_PROPS 0
-#define EFSYS_OPT_PHY_BIST 1
+#define EFSYS_OPT_PHY_BIST 0
+#define EFSYS_OPT_BIST 1
#define EFSYS_OPT_PHY_LED_CONTROL 1
#define EFSYS_OPT_PHY_FLAGS 0
@@ -276,7 +282,8 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_WOL 1
#define EFSYS_OPT_RX_SCALE 1
#define EFSYS_OPT_QSTATS 1
-#define EFSYS_OPT_FILTER 0
+#define EFSYS_OPT_FILTER 1
+#define EFSYS_OPT_MCAST_FILTER_LIST 1
#define EFSYS_OPT_RX_SCATTER 0
#define EFSYS_OPT_RX_HDR_SPLIT 0
@@ -618,6 +625,9 @@ typedef struct efsys_mem_s {
#define EFSYS_MEM_ADDR(_esmp) \
((_esmp)->esm_addr)
+#define EFSYS_MEM_IS_NULL(_esmp) \
+ ((_esmp)->esm_base == NULL)
+
/* BAR */
#define SFXGE_LOCK_NAME_MAX 16
@@ -880,6 +890,24 @@ typedef struct efsys_bar_s {
} while (B_FALSE)
#endif
+/*
+ * Guarantees 64bit aligned 64bit writes to write combined BAR mapping
+ * (required by PIO hardware)
+ */
+#define EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp) \
+ do { \
+ _NOTE(CONSTANTCONDITION) \
+ KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
+ ("not power of 2 aligned")); \
+ \
+ (void) (_esbp); \
+ \
+ /* FIXME: Perform a 64-bit write */ \
+ KASSERT(0, ("not implemented")); \
+ \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
#if defined(SFXGE_USE_BUS_SPACE_8)
#define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \
do { \
@@ -979,6 +1007,13 @@ typedef struct efsys_bar_s {
} while (B_FALSE)
#endif
+/* Use the standard octo-word write for doorbell writes */
+#define EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop) \
+ do { \
+ EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
/* SPIN */
#define EFSYS_SPIN(_us) \
@@ -994,6 +1029,23 @@ typedef struct efsys_bar_s {
#define EFSYS_MEM_READ_BARRIER() rmb()
#define EFSYS_PIO_WRITE_BARRIER()
+/* DMA SYNC */
+#define EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size) \
+ do { \
+ bus_dmamap_sync((_esmp)->esm_tag, \
+ (_esmp)->esm_map, \
+ BUS_DMASYNC_POSTREAD); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
+#define EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size) \
+ do { \
+ bus_dmamap_sync((_esmp)->esm_tag, \
+ (_esmp)->esm_map, \
+ BUS_DMASYNC_PREWRITE); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
/* TIMESTAMP */
typedef clock_t efsys_timestamp_t;
@@ -1150,7 +1202,7 @@ extern void sfxge_err(efsys_identifier_t *, unsigned int,
#define EFSYS_ASSERT(_exp) do { \
if (!(_exp)) \
- panic(#_exp); \
+ panic("%s", #_exp); \
} while (0)
#define EFSYS_ASSERT3(_x, _op, _y, _t) do { \
@@ -1164,6 +1216,10 @@ extern void sfxge_err(efsys_identifier_t *, unsigned int,
#define EFSYS_ASSERT3S(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, int64_t)
#define EFSYS_ASSERT3P(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uintptr_t)
+/* ROTATE */
+
+#define EFSYS_HAS_ROTL_DWORD 0
+
#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h
index c5ef44877582..3435951e58fb 100644
--- a/sys/dev/sfxge/common/efx.h
+++ b/sys/dev/sfxge/common/efx.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2006-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2006-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -29,6 +34,7 @@
#define _SYS_EFX_H
#include "efsys.h"
+#include "efx_phy_ids.h"
#ifdef __cplusplus
extern "C" {
@@ -38,14 +44,13 @@ extern "C" {
#define EFX_ARRAY_SIZE(_array) (sizeof(_array) / sizeof((_array)[0]))
-#ifndef EFSYS_MEM_IS_NULL
-#define EFSYS_MEM_IS_NULL(_esmp) ((_esmp)->esm_base == NULL)
-#endif
+#define EFX_FIELD_OFFSET(_type, _field) ((size_t) &(((_type *)0)->_field))
typedef enum efx_family_e {
EFX_FAMILY_INVALID,
EFX_FAMILY_FALCON,
EFX_FAMILY_SIENA,
+ EFX_FAMILY_HUNTINGTON,
EFX_FAMILY_NTYPES
} efx_family_t;
@@ -60,11 +65,23 @@ efx_infer_family(
__in efsys_bar_t *esbp,
__out efx_family_t *efp);
-#define EFX_PCI_VENID_SFC 0x1924
-#define EFX_PCI_DEVID_FALCON 0x0710
-#define EFX_PCI_DEVID_BETHPAGE 0x0803
-#define EFX_PCI_DEVID_SIENA 0x0813
-#define EFX_PCI_DEVID_SIENA_F1_UNINIT 0x0810
+#define EFX_PCI_VENID_SFC 0x1924
+
+#define EFX_PCI_DEVID_FALCON 0x0710 /* SFC4000 */
+
+#define EFX_PCI_DEVID_BETHPAGE 0x0803 /* SFC9020 */
+#define EFX_PCI_DEVID_SIENA 0x0813 /* SFL9021 */
+#define EFX_PCI_DEVID_SIENA_F1_UNINIT 0x0810
+
+#define EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT 0x0901
+#define EFX_PCI_DEVID_FARMINGDALE 0x0903 /* SFC9120 PF */
+#define EFX_PCI_DEVID_HUNTINGTON 0x0913 /* SFL9122 PF */
+#define EFX_PCI_DEVID_GREENPORT 0x0923 /* SFC9140 PF */
+
+#define EFX_PCI_DEVID_FARMINGDALE_VF 0x1903 /* SFC9120 VF */
+#define EFX_PCI_DEVID_HUNTINGTON_VF 0x1913 /* SFL9122 VF */
+#define EFX_PCI_DEVID_GREENPORT_VF 0x1923 /* SFC9140 VF */
+
#define EFX_MEM_BAR 2
@@ -86,10 +103,27 @@ enum {
EFX_ERR_NCODES
};
+/* Calculate the IEEE 802.3 CRC32 of a MAC addr */
+extern __checkReturn uint32_t
+efx_crc32_calculate(
+ __in uint32_t crc_init,
+ __in_ecount(length) uint8_t const *input,
+ __in int length);
+
+
+/* Type prototypes */
+
+typedef struct efx_rxq_s efx_rxq_t;
+
/* NIC */
typedef struct efx_nic_s efx_nic_t;
+#define EFX_NIC_FUNC_PRIMARY 0x00000001
+#define EFX_NIC_FUNC_LINKCTRL 0x00000002
+#define EFX_NIC_FUNC_TRUSTED 0x00000004
+
+
extern __checkReturn int
efx_nic_create(
__in efx_family_t family,
@@ -145,6 +179,11 @@ efx_nic_destroy(
#if EFSYS_OPT_MCDI
+#if EFSYS_OPT_HUNTINGTON
+/* Huntington requires MCDIv2 commands */
+#define WITH_MCDI_V2 1
+#endif
+
typedef struct efx_mcdi_req_s efx_mcdi_req_t;
typedef enum efx_mcdi_exception_e {
@@ -154,6 +193,7 @@ typedef enum efx_mcdi_exception_e {
typedef struct efx_mcdi_transport_s {
void *emt_context;
+ efsys_mem_t *emt_dma_mem;
void (*emt_execute)(void *, efx_mcdi_req_t *);
void (*emt_ev_cpl)(void *);
void (*emt_exception)(void *, efx_mcdi_exception_t);
@@ -168,6 +208,10 @@ extern __checkReturn int
efx_mcdi_reboot(
__in efx_nic_t *enp);
+ void
+efx_mcdi_new_epoch(
+ __in efx_nic_t *enp);
+
extern void
efx_mcdi_request_start(
__in efx_nic_t *enp,
@@ -251,7 +295,7 @@ efx_intr_fini(
#if EFSYS_OPT_MAC_STATS
-/* START MKCONFIG GENERATED EfxHeaderMacBlock bb8d39428b6fdcf5 */
+/* START MKCONFIG GENERATED EfxHeaderMacBlock e323546097fd7c65 */
typedef enum efx_mac_stat_e {
EFX_MAC_RX_OCTETS,
EFX_MAC_RX_PKTS,
@@ -304,6 +348,36 @@ typedef enum efx_mac_stat_e {
EFX_MAC_TX_LATE_COL_PKTS,
EFX_MAC_TX_DEF_PKTS,
EFX_MAC_TX_EX_DEF_PKTS,
+ EFX_MAC_PM_TRUNC_BB_OVERFLOW,
+ EFX_MAC_PM_DISCARD_BB_OVERFLOW,
+ EFX_MAC_PM_TRUNC_VFIFO_FULL,
+ EFX_MAC_PM_DISCARD_VFIFO_FULL,
+ EFX_MAC_PM_TRUNC_QBB,
+ EFX_MAC_PM_DISCARD_QBB,
+ EFX_MAC_PM_DISCARD_MAPPING,
+ EFX_MAC_RXDP_Q_DISABLED_PKTS,
+ EFX_MAC_RXDP_DI_DROPPED_PKTS,
+ EFX_MAC_RXDP_STREAMING_PKTS,
+ EFX_MAC_RXDP_HLB_FETCH,
+ EFX_MAC_RXDP_HLB_WAIT,
+ EFX_MAC_VADAPTER_RX_UNICAST_PACKETS,
+ EFX_MAC_VADAPTER_RX_UNICAST_BYTES,
+ EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS,
+ EFX_MAC_VADAPTER_RX_MULTICAST_BYTES,
+ EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS,
+ EFX_MAC_VADAPTER_RX_BROADCAST_BYTES,
+ EFX_MAC_VADAPTER_RX_BAD_PACKETS,
+ EFX_MAC_VADAPTER_RX_BAD_BYTES,
+ EFX_MAC_VADAPTER_RX_OVERFLOW,
+ EFX_MAC_VADAPTER_TX_UNICAST_PACKETS,
+ EFX_MAC_VADAPTER_TX_UNICAST_BYTES,
+ EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS,
+ EFX_MAC_VADAPTER_TX_MULTICAST_BYTES,
+ EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS,
+ EFX_MAC_VADAPTER_TX_BROADCAST_BYTES,
+ EFX_MAC_VADAPTER_TX_BAD_PACKETS,
+ EFX_MAC_VADAPTER_TX_BAD_BYTES,
+ EFX_MAC_VADAPTER_TX_OVERFLOW,
EFX_MAC_NSTATS
} efx_mac_stat_t;
@@ -321,9 +395,16 @@ typedef enum efx_link_mode_e {
EFX_LINK_1000HDX,
EFX_LINK_1000FDX,
EFX_LINK_10000FDX,
+ EFX_LINK_40000FDX,
EFX_LINK_NMODES
} efx_link_mode_t;
+#define EFX_MAC_ADDR_LEN 6
+
+#define EFX_MAC_ADDR_IS_MULTICAST(_address) (((uint8_t*)_address)[0] & 0x01)
+
+#define EFX_MAC_MULTICAST_LIST_MAX 256
+
#define EFX_MAC_SDU_MAX 9202
#define EFX_MAC_PDU(_sdu) \
@@ -347,11 +428,29 @@ efx_mac_addr_set(
__in efx_nic_t *enp,
__in uint8_t *addr);
-extern __checkReturn int
+extern __checkReturn int
efx_mac_filter_set(
+ __in efx_nic_t *enp,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst);
+
+extern __checkReturn int
+efx_mac_multicast_list_set(
+ __in efx_nic_t *enp,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count);
+
+extern __checkReturn int
+efx_mac_filter_default_rxq_set(
__in efx_nic_t *enp,
- __in boolean_t unicst,
- __in boolean_t brdcst);
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss);
+
+extern void
+efx_mac_filter_default_rxq_clear(
+ __in efx_nic_t *enp);
extern __checkReturn int
efx_mac_drain(
@@ -381,15 +480,41 @@ efx_mac_fcntl_get(
#define EFX_MAC_HASH_BITS (1 << 8)
extern __checkReturn int
+efx_pktfilter_init(
+ __in efx_nic_t *enp);
+
+extern void
+efx_pktfilter_fini(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_pktfilter_set(
+ __in efx_nic_t *enp,
+ __in boolean_t unicst,
+ __in boolean_t brdcst);
+
+extern __checkReturn int
efx_mac_hash_set(
__in efx_nic_t *enp,
__in_ecount(EFX_MAC_HASH_BITS) unsigned int const *bucket);
+#if EFSYS_OPT_MCAST_FILTER_LIST
+extern __checkReturn int
+efx_pktfilter_mcast_list_set(
+ __in efx_nic_t *enp,
+ __in uint8_t const *addrs,
+ __in int count);
+#endif /* EFSYS_OPT_MCAST_FILTER_LIST */
+
+extern __checkReturn int
+efx_pktfilter_mcast_all(
+ __in efx_nic_t *enp);
+
#if EFSYS_OPT_MAC_STATS
#if EFSYS_OPT_NAMES
-extern __checkReturn const char __cs *
+extern __checkReturn const char *
efx_mac_stat_name(
__in efx_nic_t *enp,
__in unsigned int id);
@@ -440,12 +565,13 @@ typedef enum efx_mon_type_e {
EFX_MON_LM87,
EFX_MON_MAX6647,
EFX_MON_SFC90X0,
+ EFX_MON_SFC91X0,
EFX_MON_NTYPES
} efx_mon_type_t;
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_mon_name(
__in efx_nic_t *enp);
@@ -457,9 +583,10 @@ efx_mon_init(
#if EFSYS_OPT_MON_STATS
-#define EFX_MON_STATS_SIZE 0x100
+#define EFX_MON_STATS_PAGE_SIZE 0x100
+#define EFX_MON_MASK_ELEMENT_SIZE 32
-/* START MKCONFIG GENERATED MonitorHeaderStatsBlock 58706a378332aeee */
+/* START MKCONFIG GENERATED MonitorHeaderStatsBlock c79c86b62a144846 */
typedef enum efx_mon_stat_e {
EFX_MON_STAT_2_5V,
EFX_MON_STAT_VCCP1,
@@ -491,6 +618,45 @@ typedef enum efx_mon_stat_e {
EFX_MON_STAT_VAOE_IN,
EFX_MON_STAT_IAOE,
EFX_MON_STAT_IAOE_IN,
+ EFX_MON_STAT_NIC_POWER,
+ EFX_MON_STAT_0_9V,
+ EFX_MON_STAT_I0_9V,
+ EFX_MON_STAT_I1_2V,
+ EFX_MON_STAT_0_9V_ADC,
+ EFX_MON_STAT_INT_TEMP2,
+ EFX_MON_STAT_VREG_TEMP,
+ EFX_MON_STAT_VREG_0_9V_TEMP,
+ EFX_MON_STAT_VREG_1_2V_TEMP,
+ EFX_MON_STAT_INT_VPTAT,
+ EFX_MON_STAT_INT_ADC_TEMP,
+ EFX_MON_STAT_EXT_VPTAT,
+ EFX_MON_STAT_EXT_ADC_TEMP,
+ EFX_MON_STAT_AMBIENT_TEMP,
+ EFX_MON_STAT_AIRFLOW,
+ EFX_MON_STAT_VDD08D_VSS08D_CSR,
+ EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC,
+ EFX_MON_STAT_HOTPOINT_TEMP,
+ EFX_MON_STAT_PHY_POWER_SWITCH_PORT0,
+ EFX_MON_STAT_PHY_POWER_SWITCH_PORT1,
+ EFX_MON_STAT_MUM_VCC,
+ EFX_MON_STAT_0V9_A,
+ EFX_MON_STAT_I0V9_A,
+ EFX_MON_STAT_0V9_A_TEMP,
+ EFX_MON_STAT_0V9_B,
+ EFX_MON_STAT_I0V9_B,
+ EFX_MON_STAT_0V9_B_TEMP,
+ EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY,
+ EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXT_ADC,
+ EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY,
+ EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_MASTER_VPTAT,
+ EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP,
+ EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT,
+ EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP,
+ EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC,
EFX_MON_NSTATS
} efx_mon_stat_t;
@@ -501,16 +667,17 @@ typedef enum efx_mon_stat_state_e {
EFX_MON_STAT_STATE_WARNING = 1,
EFX_MON_STAT_STATE_FATAL = 2,
EFX_MON_STAT_STATE_BROKEN = 3,
+ EFX_MON_STAT_STATE_NO_READING = 4,
} efx_mon_stat_state_t;
-typedef struct efx_mon_stat_value_t {
+typedef struct efx_mon_stat_value_s {
uint16_t emsv_value;
uint16_t emsv_state;
} efx_mon_stat_value_t;
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_mon_stat_name(
__in efx_nic_t *enp,
__in efx_mon_stat_t id);
@@ -540,16 +707,6 @@ efx_mon_fini(
#define MAXMMD ((1 << 5) - 1)
-/* PHY types */
-#define EFX_PHY_NULL 0x0
-#define EFX_PHY_TXC43128 0x1
-#define EFX_PHY_SFX7101 0x3
-#define EFX_PHY_QT2022C2 0x4
-#define EFX_PHY_SFT9001A 0x8
-#define EFX_PHY_QT2025C 0x9
-#define EFX_PHY_SFT9001B 0xa
-#define EFX_PHY_QLX111V 0xc
-
extern __checkReturn int
efx_phy_verify(
__in efx_nic_t *enp);
@@ -596,26 +753,38 @@ typedef enum efx_loopback_type_e {
EFX_LOOPBACK_PHY_XS = 15,
EFX_LOOPBACK_PCS = 16,
EFX_LOOPBACK_PMA_PMD = 17,
+ EFX_LOOPBACK_XPORT = 18,
+ EFX_LOOPBACK_XGMII_WS = 19,
+ EFX_LOOPBACK_XAUI_WS = 20,
+ EFX_LOOPBACK_XAUI_WS_FAR = 21,
+ EFX_LOOPBACK_XAUI_WS_NEAR = 22,
+ EFX_LOOPBACK_GMII_WS = 23,
+ EFX_LOOPBACK_XFI_WS = 24,
+ EFX_LOOPBACK_XFI_WS_FAR = 25,
+ EFX_LOOPBACK_PHYXS_WS = 26,
+ EFX_LOOPBACK_PMA_INT = 27,
+ EFX_LOOPBACK_SD_NEAR = 28,
+ EFX_LOOPBACK_SD_FAR = 29,
+ EFX_LOOPBACK_PMA_INT_WS = 30,
+ EFX_LOOPBACK_SD_FEP2_WS = 31,
+ EFX_LOOPBACK_SD_FEP1_5_WS = 32,
+ EFX_LOOPBACK_SD_FEP_WS = 33,
+ EFX_LOOPBACK_SD_FES_WS = 34,
EFX_LOOPBACK_NTYPES
} efx_loopback_type_t;
-#define EFX_LOOPBACK_MAC_MASK \
- ((1 << EFX_LOOPBACK_DATA) | \
- (1 << EFX_LOOPBACK_GMAC) | \
- (1 << EFX_LOOPBACK_XGMII) | \
- (1 << EFX_LOOPBACK_XGXS) | \
- (1 << EFX_LOOPBACK_XAUI) | \
- (1 << EFX_LOOPBACK_GMII) | \
- (1 << EFX_LOOPBACK_SGMII) | \
- (1 << EFX_LOOPBACK_XGBR) | \
- (1 << EFX_LOOPBACK_XFI) | \
- (1 << EFX_LOOPBACK_XAUI_FAR) | \
- (1 << EFX_LOOPBACK_GMII_FAR) | \
- (1 << EFX_LOOPBACK_SGMII_FAR) | \
- (1 << EFX_LOOPBACK_XFI_FAR))
-
-#define EFX_LOOPBACK_MASK \
- ((1 << EFX_LOOPBACK_NTYPES) - 1)
+typedef enum efx_loopback_kind_e {
+ EFX_LOOPBACK_KIND_OFF = 0,
+ EFX_LOOPBACK_KIND_ALL,
+ EFX_LOOPBACK_KIND_MAC,
+ EFX_LOOPBACK_KIND_PHY,
+ EFX_LOOPBACK_NKINDS
+} efx_loopback_kind_t;
+
+extern void
+efx_loopback_mask(
+ __in efx_loopback_kind_t loopback_kind,
+ __out efx_qword_t *maskp);
extern __checkReturn int
efx_port_loopback_set(
@@ -625,7 +794,7 @@ efx_port_loopback_set(
#if EFSYS_OPT_NAMES
-extern __checkReturn const char __cs *
+extern __checkReturn const char *
efx_loopback_type_name(
__in efx_nic_t *enp,
__in efx_loopback_type_t type);
@@ -637,7 +806,7 @@ efx_loopback_type_name(
extern __checkReturn int
efx_port_poll(
__in efx_nic_t *enp,
- __out efx_link_mode_t *link_modep);
+ __out_opt efx_link_mode_t *link_modep);
extern void
efx_port_fini(
@@ -655,6 +824,7 @@ typedef enum efx_phy_cap_type_e {
EFX_PHY_CAP_PAUSE,
EFX_PHY_CAP_ASYM,
EFX_PHY_CAP_AN,
+ EFX_PHY_CAP_40000FDX,
EFX_PHY_CAP_NTYPES
} efx_phy_cap_type_t;
@@ -692,6 +862,7 @@ typedef enum efx_phy_media_type_e {
EFX_PHY_MEDIA_XFP,
EFX_PHY_MEDIA_SFP_PLUS,
EFX_PHY_MEDIA_BASE_T,
+ EFX_PHY_MEDIA_QSFP_PLUS,
EFX_PHY_MEDIA_NTYPES
} efx_phy_media_type_t;
@@ -762,7 +933,7 @@ typedef enum efx_phy_stat_e {
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_phy_stat_name(
__in efx_nic_t *enp,
__in efx_phy_stat_t stat);
@@ -783,7 +954,7 @@ efx_phy_stats_update(
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id);
@@ -807,22 +978,25 @@ efx_phy_prop_set(
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
-
-typedef enum efx_phy_bist_type_e {
- EFX_PHY_BIST_TYPE_UNKNOWN,
- EFX_PHY_BIST_TYPE_NORMAL,
- EFX_PHY_BIST_TYPE_CABLE_SHORT,
- EFX_PHY_BIST_TYPE_CABLE_LONG,
- EFX_PHY_BIST_TYPE_NTYPES,
-} efx_phy_bist_type_t;
-
-typedef enum efx_phy_bist_result_e {
- EFX_PHY_BIST_RESULT_UNKNOWN,
- EFX_PHY_BIST_RESULT_RUNNING,
- EFX_PHY_BIST_RESULT_PASSED,
- EFX_PHY_BIST_RESULT_FAILED,
-} efx_phy_bist_result_t;
+#if EFSYS_OPT_BIST
+
+typedef enum efx_bist_type_e {
+ EFX_BIST_TYPE_UNKNOWN,
+ EFX_BIST_TYPE_PHY_NORMAL,
+ EFX_BIST_TYPE_PHY_CABLE_SHORT,
+ EFX_BIST_TYPE_PHY_CABLE_LONG,
+ EFX_BIST_TYPE_MC_MEM, /* Test the MC DMEM and IMEM */
+ EFX_BIST_TYPE_SAT_MEM, /* Test the DMEM and IMEM of satellite cpus*/
+ EFX_BIST_TYPE_REG, /* Test the register memories */
+ EFX_BIST_TYPE_NTYPES,
+} efx_bist_type_t;
+
+typedef enum efx_bist_result_e {
+ EFX_BIST_RESULT_UNKNOWN,
+ EFX_BIST_RESULT_RUNNING,
+ EFX_BIST_RESULT_PASSED,
+ EFX_BIST_RESULT_FAILED,
+} efx_bist_result_t;
typedef enum efx_phy_cable_status_e {
EFX_PHY_CABLE_STATUS_OK,
@@ -833,39 +1007,53 @@ typedef enum efx_phy_cable_status_e {
EFX_PHY_CABLE_STATUS_BUSY,
} efx_phy_cable_status_t;
-typedef enum efx_phy_bist_value_e {
- EFX_PHY_BIST_CABLE_LENGTH_A,
- EFX_PHY_BIST_CABLE_LENGTH_B,
- EFX_PHY_BIST_CABLE_LENGTH_C,
- EFX_PHY_BIST_CABLE_LENGTH_D,
- EFX_PHY_BIST_CABLE_STATUS_A,
- EFX_PHY_BIST_CABLE_STATUS_B,
- EFX_PHY_BIST_CABLE_STATUS_C,
- EFX_PHY_BIST_CABLE_STATUS_D,
- EFX_PHY_BIST_FAULT_CODE,
- EFX_PHY_BIST_NVALUES,
-} efx_phy_bist_value_t;
+typedef enum efx_bist_value_e {
+ EFX_BIST_PHY_CABLE_LENGTH_A,
+ EFX_BIST_PHY_CABLE_LENGTH_B,
+ EFX_BIST_PHY_CABLE_LENGTH_C,
+ EFX_BIST_PHY_CABLE_LENGTH_D,
+ EFX_BIST_PHY_CABLE_STATUS_A,
+ EFX_BIST_PHY_CABLE_STATUS_B,
+ EFX_BIST_PHY_CABLE_STATUS_C,
+ EFX_BIST_PHY_CABLE_STATUS_D,
+ EFX_BIST_FAULT_CODE,
+ /* Memory BIST specific values. These match to the MC_CMD_BIST_POLL
+ * response. */
+ EFX_BIST_MEM_TEST,
+ EFX_BIST_MEM_ADDR,
+ EFX_BIST_MEM_BUS,
+ EFX_BIST_MEM_EXPECT,
+ EFX_BIST_MEM_ACTUAL,
+ EFX_BIST_MEM_ECC,
+ EFX_BIST_MEM_ECC_PARITY,
+ EFX_BIST_MEM_ECC_FATAL,
+ EFX_BIST_NVALUES,
+} efx_bist_value_t;
+
+extern __checkReturn int
+efx_bist_enable_offline(
+ __in efx_nic_t *enp);
extern __checkReturn int
-efx_phy_bist_start(
+efx_bist_start(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type);
+ __in efx_bist_type_t type);
extern __checkReturn int
-efx_phy_bist_poll(
+efx_bist_poll(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type,
- __out efx_phy_bist_result_t *resultp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
__out_opt uint32_t *value_maskp,
__out_ecount_opt(count) unsigned long *valuesp,
__in size_t count);
extern void
-efx_phy_bist_stop(
+efx_bist_stop(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type);
+ __in efx_bist_type_t type);
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
#define EFX_FEATURE_IPV6 0x00000001
#define EFX_FEATURE_LFSR_HASH_INSERT 0x00000002
@@ -876,6 +1064,10 @@ efx_phy_bist_stop(
#define EFX_FEATURE_LOOKAHEAD_SPLIT 0x00000040
#define EFX_FEATURE_MAC_HEADER_FILTERS 0x00000080
#define EFX_FEATURE_TURBO 0x00000100
+#define EFX_FEATURE_MCDI_DMA 0x00000200
+#define EFX_FEATURE_TX_SRC_FILTERS 0x00000400
+#define EFX_FEATURE_PIO_BUFFERS 0x00000800
+#define EFX_FEATURE_FW_ASSISTED_TSO 0x00001000
typedef struct efx_nic_cfg_s {
uint32_t enc_board_type;
@@ -886,20 +1078,29 @@ typedef struct efx_nic_cfg_s {
char enc_phy_revision[21];
efx_mon_type_t enc_mon_type;
#if EFSYS_OPT_MON_STATS
- uint32_t enc_mon_stat_mask;
+ uint32_t enc_mon_stat_dma_buf_size;
+ uint32_t enc_mon_stat_mask[(EFX_MON_NSTATS + 31) / 32];
#endif
unsigned int enc_features;
uint8_t enc_mac_addr[6];
- uint8_t enc_port;
+ uint8_t enc_port; /* PHY port number */
+ uint32_t enc_func_flags;
+ uint32_t enc_intr_vec_base;
+ uint32_t enc_intr_limit;
uint32_t enc_evq_limit;
uint32_t enc_txq_limit;
uint32_t enc_rxq_limit;
uint32_t enc_buftbl_limit;
+ uint32_t enc_piobuf_limit;
+ uint32_t enc_piobuf_size;
uint32_t enc_evq_timer_quantum_ns;
uint32_t enc_evq_timer_max_us;
uint32_t enc_clk_mult;
+ uint32_t enc_rx_prefix_size;
+ uint32_t enc_rx_buf_align_start;
+ uint32_t enc_rx_buf_align_end;
#if EFSYS_OPT_LOOPBACK
- uint32_t enc_loopback_types[EFX_LINK_NMODES];
+ efx_qword_t enc_loopback_types[EFX_LINK_NMODES];
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_PHY_FLAGS
uint32_t enc_phy_flags_mask;
@@ -914,23 +1115,100 @@ typedef struct efx_nic_cfg_s {
unsigned int enc_phy_nprops;
#endif /* EFSYS_OPT_PHY_PROPS */
#if EFSYS_OPT_SIENA
- uint8_t enc_siena_channel;
+ uint8_t enc_mcdi_mdio_channel;
#if EFSYS_OPT_PHY_STATS
- uint32_t enc_siena_phy_stat_mask;
+ uint32_t enc_mcdi_phy_stat_mask;
#endif /* EFSYS_OPT_PHY_STATS */
+#endif /* EFSYS_OPT_SIENA */
+#if (EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
#if EFSYS_OPT_MON_STATS
- uint32_t enc_siena_mon_stat_mask;
+ uint32_t *enc_mcdi_sensor_maskp;
+ uint32_t enc_mcdi_sensor_mask_size;
#endif /* EFSYS_OPT_MON_STATS */
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_PHY_BIST
+#endif /* (EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON) */
+#if EFSYS_OPT_BIST
uint32_t enc_bist_mask;
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
+#if EFSYS_OPT_HUNTINGTON
+ uint32_t enc_pf;
+ uint32_t enc_vf;
+ uint32_t enc_privilege_mask;
+#endif /* EFSYS_OPT_HUNTINGTON */
+ boolean_t enc_bug26807_workaround;
+ boolean_t enc_bug35388_workaround;
+ boolean_t enc_bug41750_workaround;
+ boolean_t enc_rx_batching_enabled;
+ /* Maximum number of descriptors completed in an rx event. */
+ uint32_t enc_rx_batch_max;
+ /* Number of rx descriptors the hardware requires for a push. */
+ uint32_t enc_rx_push_align;
+ /*
+ * Maximum number of bytes into the packet the TCP header can start for
+ * the hardware to apply TSO packet edits.
+ */
+ uint32_t enc_tx_tso_tcp_header_offset_limit;
+ boolean_t enc_fw_assisted_tso_enabled;
+ boolean_t enc_hw_tx_insert_vlan_enabled;
+ /* Datapath firmware vadapter/vport/vswitch support */
+ boolean_t enc_datapath_cap_evb;
+ /* External port identifier */
+ uint8_t enc_external_port;
} efx_nic_cfg_t;
+#define EFX_PCI_FUNCTION_IS_PF(_encp) ((_encp)->enc_vf == 0xffff)
+#define EFX_PCI_FUNCTION_IS_VF(_encp) ((_encp)->enc_vf != 0xffff)
+
+#define EFX_PCI_FUNCTION(_encp) \
+ (EFX_PCI_FUNCTION_IS_PF(_encp) ? (_encp)->enc_pf : (_encp)->enc_vf)
+
+#define EFX_PCI_VF_PARENT(_encp) ((_encp)->enc_pf)
+
extern const efx_nic_cfg_t *
efx_nic_cfg_get(
__in efx_nic_t *enp);
+/* Driver resource limits (minimum required/maximum usable). */
+typedef struct efx_drv_limits_s
+{
+ uint32_t edl_min_evq_count;
+ uint32_t edl_max_evq_count;
+
+ uint32_t edl_min_rxq_count;
+ uint32_t edl_max_rxq_count;
+
+ uint32_t edl_min_txq_count;
+ uint32_t edl_max_txq_count;
+
+ /* PIO blocks (sub-allocated from piobuf) */
+ uint32_t edl_min_pio_alloc_size;
+ uint32_t edl_max_pio_alloc_count;
+} efx_drv_limits_t;
+
+extern __checkReturn int
+efx_nic_set_drv_limits(
+ __inout efx_nic_t *enp,
+ __in efx_drv_limits_t *edlp);
+
+typedef enum efx_nic_region_e {
+ EFX_REGION_VI, /* Memory BAR UC mapping */
+ EFX_REGION_PIO_WRITE_VI, /* Memory BAR WC mapping */
+} efx_nic_region_t;
+
+extern __checkReturn int
+efx_nic_get_bar_region(
+ __in efx_nic_t *enp,
+ __in efx_nic_region_t region,
+ __out uint32_t *offsetp,
+ __out size_t *sizep);
+
+extern __checkReturn int
+efx_nic_get_vi_pool(
+ __in efx_nic_t *enp,
+ __out uint32_t *evq_countp,
+ __out uint32_t *rxq_countp,
+ __out uint32_t *txq_countp);
+
+
#if EFSYS_OPT_VPD
typedef enum efx_vpd_tag_e {
@@ -1029,6 +1307,7 @@ typedef enum efx_nvram_type_e {
EFX_NVRAM_FCFW,
EFX_NVRAM_CPLD,
EFX_NVRAM_FPGA_BACKUP,
+ EFX_NVRAM_DYNAMIC_CFG,
EFX_NVRAM_NTYPES,
} efx_nvram_type_t;
@@ -1080,7 +1359,15 @@ extern __checkReturn int
efx_nvram_set_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint16_t version[4]);
+ __in_ecount(4) uint16_t version[4]);
+
+/* Validate contents of TLV formatted partition */
+extern __checkReturn int
+efx_nvram_tlv_validate(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size);
extern __checkReturn int
efx_nvram_erase(
@@ -1246,12 +1533,11 @@ typedef struct efx_evq_s efx_evq_t;
#if EFSYS_OPT_QSTATS
-/* START MKCONFIG GENERATED EfxHeaderEventQueueBlock d5614a5d669c8ca3 */
+/* START MKCONFIG GENERATED EfxHeaderEventQueueBlock 6f3843f5fe7cc843 */
typedef enum efx_ev_qstat_e {
EV_ALL,
EV_RX,
EV_RX_OK,
- EV_RX_RECOVERY,
EV_RX_FRM_TRUNC,
EV_RX_TOBE_DISC,
EV_RX_PAUSE_FRM_ERR,
@@ -1269,16 +1555,14 @@ typedef enum efx_ev_qstat_e {
EV_RX_OTHER_IPV4,
EV_RX_OTHER_IPV6,
EV_RX_NON_IP,
- EV_RX_OVERRUN,
+ EV_RX_BATCH,
EV_TX,
EV_TX_WQ_FF_FULL,
EV_TX_PKT_ERR,
EV_TX_PKT_TOO_BIG,
EV_TX_UNEXPECTED,
EV_GLOBAL,
- EV_GLOBAL_PHY,
EV_GLOBAL_MNT,
- EV_GLOBAL_RX_RECOVERY,
EV_DRIVER,
EV_DRIVER_SRM_UPD_DONE,
EV_DRIVER_TX_DESCQ_FLS_DONE,
@@ -1303,13 +1587,9 @@ extern void
efx_ev_fini(
__in efx_nic_t *enp);
-#define EFX_MASK(_max, _min) (-((_max) << 1) ^ -(_min))
-
#define EFX_EVQ_MAXNEVS 32768
#define EFX_EVQ_MINNEVS 512
-#define EFX_EVQ_NEVS_MASK EFX_MASK(EFX_EVQ_MAXNEVS, EFX_EVQ_MINNEVS)
-
#define EFX_EVQ_SIZE(_nevs) ((_nevs) * sizeof (efx_qword_t))
#define EFX_EVQ_NBUFS(_nevs) (EFX_EVQ_SIZE(_nevs) / EFX_BUF_SIZE)
@@ -1345,6 +1625,7 @@ typedef __checkReturn boolean_t
#define EFX_PKT_IPV4 0x0800
#define EFX_PKT_IPV6 0x1000
+#define EFX_PKT_PREFIX_LEN 0x2000
#define EFX_ADDR_MISMATCH 0x4000
#define EFX_DISCARD 0x8000
@@ -1371,6 +1652,9 @@ typedef __checkReturn boolean_t
#define EFX_EXCEPTION_UNKNOWN_SENSOREVT 0x00000004
#define EFX_EXCEPTION_FWALERT_SRAM 0x00000005
#define EFX_EXCEPTION_UNKNOWN_FWALERT 0x00000006
+#define EFX_EXCEPTION_RX_ERROR 0x00000007
+#define EFX_EXCEPTION_TX_ERROR 0x00000008
+#define EFX_EXCEPTION_EV_ERROR 0x00000009
typedef __checkReturn boolean_t
(*efx_exception_ev_t)(
@@ -1460,7 +1744,7 @@ typedef struct efx_ev_callbacks_s {
#endif /* EFSYS_OPT_MON_STATS */
#if EFSYS_OPT_MAC_STATS
efx_mac_stats_ev_t eec_mac_stats;
-#endif /* EFSYS_OPT_MON_STATS */
+#endif /* EFSYS_OPT_MAC_STATS */
} efx_ev_callbacks_t;
extern __checkReturn boolean_t
@@ -1498,7 +1782,7 @@ efx_ev_qprime(
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_ev_qstat_name(
__in efx_nic_t *enp,
__in unsigned int id);
@@ -1518,11 +1802,9 @@ efx_ev_qdestroy(
/* RX */
-typedef struct efx_rxq_s efx_rxq_t;
-
extern __checkReturn int
efx_rx_init(
- __in efx_nic_t *enp);
+ __inout efx_nic_t *enp);
extern void
efx_rx_fini(
@@ -1558,10 +1840,32 @@ typedef enum efx_rx_hash_type_e {
EFX_RX_HASH_TCPIPV6,
} efx_rx_hash_type_t;
+typedef enum efx_rx_hash_support_e {
+ EFX_RX_HASH_UNAVAILABLE = 0, /* Hardware hash not inserted */
+ EFX_RX_HASH_AVAILABLE /* Insert hash with/without RSS */
+} efx_rx_hash_support_t;
+
#define EFX_RSS_TBL_SIZE 128 /* Rows in RX indirection table */
#define EFX_MAXRSS 64 /* RX indirection entry range */
#define EFX_MAXRSS_LEGACY 16 /* See bug16611 and bug17213 */
+typedef enum efx_rx_scale_support_e {
+ EFX_RX_SCALE_UNAVAILABLE = 0, /* Not supported */
+ EFX_RX_SCALE_EXCLUSIVE, /* Writable key/indirection table */
+ EFX_RX_SCALE_SHARED /* Read-only key/indirection table */
+} efx_rx_scale_support_t;
+
+ extern __checkReturn int
+efx_rx_hash_support_get(
+ __in efx_nic_t *enp,
+ __out efx_rx_hash_support_t *supportp);
+
+
+extern __checkReturn int
+efx_rx_scale_support_get(
+ __in efx_nic_t *enp,
+ __out efx_rx_scale_support_t *supportp);
+
extern __checkReturn int
efx_rx_scale_mode_set(
__in efx_nic_t *enp,
@@ -1576,54 +1880,28 @@ efx_rx_scale_tbl_set(
__in size_t n);
extern __checkReturn int
-efx_rx_scale_toeplitz_ipv4_key_set(
+efx_rx_scale_key_set(
__in efx_nic_t *enp,
__in_ecount(n) uint8_t *key,
__in size_t n);
-extern __checkReturn int
-efx_rx_scale_toeplitz_ipv6_key_set(
+extern uint32_t
+efx_psuedo_hdr_hash_get(
__in efx_nic_t *enp,
- __in_ecount(n) uint8_t *key,
- __in size_t n);
-
-/*
- * The prefix is a byte array of one of the forms:
- *
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.TT.TT.TT.TT
- * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.LL.LL
- *
- * where:
- *
- * TT.TT.TT.TT is a 32-bit Toeplitz hash
- * LL.LL is a 16-bit LFSR hash
- *
- * Hash values are in network (big-endian) byte order.
- */
-
-#define EFX_RX_PREFIX_SIZE 16
-
-#define EFX_RX_HASH_VALUE(_func, _buffer) \
- (((_func) == EFX_RX_HASHALG_LFSR) ? \
- ((uint16_t)(((_buffer)[14] << 8) | (_buffer)[15])) : \
- ((uint32_t)(((_buffer)[12] << 24) | \
- ((_buffer)[13] << 16) | \
- ((_buffer)[14] << 8) | \
- (_buffer)[15])))
-
-#define EFX_RX_HASH_SIZE(_func) \
- (((_func) == EFX_RX_HASHALG_LFSR) ? \
- sizeof (uint16_t) : \
- sizeof (uint32_t))
+ __in efx_rx_hash_alg_t func,
+ __in uint8_t *buffer);
#endif /* EFSYS_OPT_RX_SCALE */
+extern __checkReturn int
+efx_psuedo_hdr_pkt_length_get(
+ __in efx_nic_t *enp,
+ __in uint8_t *buffer,
+ __out uint16_t *pkt_lengthp);
+
#define EFX_RXQ_MAXNDESCS 4096
#define EFX_RXQ_MINNDESCS 512
-#define EFX_RXQ_NDESCS_MASK EFX_MASK(EFX_RXQ_MAXNDESCS, EFX_RXQ_MINNDESCS)
-
#define EFX_RXQ_SIZE(_ndescs) ((_ndescs) * sizeof (efx_qword_t))
#define EFX_RXQ_NBUFS(_ndescs) (EFX_RXQ_SIZE(_ndescs) / EFX_BUF_SIZE)
#define EFX_RXQ_LIMIT(_ndescs) ((_ndescs) - 16)
@@ -1655,6 +1933,10 @@ typedef struct efx_buffer_s {
boolean_t eb_eop;
} efx_buffer_t;
+typedef struct efx_desc_s {
+ efx_qword_t ed_eq;
+} efx_desc_t;
+
extern void
efx_rx_qpost(
__in efx_rxq_t *erp,
@@ -1667,9 +1949,10 @@ efx_rx_qpost(
extern void
efx_rx_qpush(
__in efx_rxq_t *erp,
- __in unsigned int added);
+ __in unsigned int added,
+ __inout unsigned int *pushedp);
-extern void
+extern __checkReturn int
efx_rx_qflush(
__in efx_rxq_t *erp);
@@ -1687,10 +1970,10 @@ typedef struct efx_txq_s efx_txq_t;
#if EFSYS_OPT_QSTATS
-/* START MKCONFIG GENERATED EfxHeaderTransmitQueueBlock 536c5fa5014944bf */
+/* START MKCONFIG GENERATED EfxHeaderTransmitQueueBlock 12dff8778598b2db */
typedef enum efx_tx_qstat_e {
TX_POST,
- TX_UNALIGNED_SPLIT,
+ TX_POST_PIO,
TX_NQSTATS
} efx_tx_qstat_t;
@@ -1706,16 +1989,21 @@ extern void
efx_tx_fini(
__in efx_nic_t *enp);
-#define EFX_TXQ_MAXNDESCS 4096
-#define EFX_TXQ_MINNDESCS 512
+#define EFX_BUG35388_WORKAROUND(_encp) \
+ (((_encp) == NULL) ? 1 : ((_encp)->enc_bug35388_workaround != 0))
+
+#define EFX_TXQ_MAXNDESCS(_encp) \
+ ((EFX_BUG35388_WORKAROUND(_encp)) ? 2048 : 4096)
-#define EFX_TXQ_NDESCS_MASK EFX_MASK(EFX_TXQ_MAXNDESCS, EFX_TXQ_MINNDESCS)
+#define EFX_TXQ_MINNDESCS 512
#define EFX_TXQ_SIZE(_ndescs) ((_ndescs) * sizeof (efx_qword_t))
#define EFX_TXQ_NBUFS(_ndescs) (EFX_TXQ_SIZE(_ndescs) / EFX_BUF_SIZE)
#define EFX_TXQ_LIMIT(_ndescs) ((_ndescs) - 16)
#define EFX_TXQ_DC_NDESCS(_dcsize) (8 << _dcsize)
+#define EFX_TXQ_MAX_BUFS 8 /* Maximum independent of EFX_BUG35388_WORKAROUND. */
+
extern __checkReturn int
efx_tx_qcreate(
__in efx_nic_t *enp,
@@ -1726,7 +2014,8 @@ efx_tx_qcreate(
__in uint32_t id,
__in uint16_t flags,
__in efx_evq_t *eep,
- __deref_out efx_txq_t **etpp);
+ __deref_out efx_txq_t **etpp,
+ __out unsigned int *addedp);
extern __checkReturn int
efx_tx_qpost(
@@ -1741,24 +2030,77 @@ efx_tx_qpace(
__in efx_txq_t *etp,
__in unsigned int ns);
-extern void
+extern void
efx_tx_qpush(
- __in efx_txq_t *etp,
- __in unsigned int added);
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed);
-extern void
+extern __checkReturn int
efx_tx_qflush(
- __in efx_txq_t *etp);
+ __in efx_txq_t *etp);
-extern void
+extern void
efx_tx_qenable(
- __in efx_txq_t *etp);
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+efx_tx_qpio_enable(
+ __in efx_txq_t *etp);
+
+extern void
+efx_tx_qpio_disable(
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+efx_tx_qpio_write(
+ __in efx_txq_t *etp,
+ __in_ecount(buf_length) uint8_t *buffer,
+ __in size_t buf_length,
+ __in size_t pio_buf_offset);
+
+extern __checkReturn int
+efx_tx_qpio_post(
+ __in efx_txq_t *etp,
+ __in size_t pkt_length,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+extern __checkReturn int
+efx_tx_qdesc_post(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_desc_t *ed,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+extern void
+efx_tx_qdesc_dma_create(
+ __in efx_txq_t *etp,
+ __in efsys_dma_addr_t addr,
+ __in size_t size,
+ __in boolean_t eop,
+ __out efx_desc_t *edp);
+
+extern void
+efx_tx_qdesc_tso_create(
+ __in efx_txq_t *etp,
+ __in uint16_t ipv4_id,
+ __in uint32_t tcp_seq,
+ __in uint8_t tcp_flags,
+ __out efx_desc_t *edp);
+
+extern void
+efx_tx_qdesc_vlantci_create(
+ __in efx_txq_t *etp,
+ __in uint16_t tci,
+ __out efx_desc_t *edp);
#if EFSYS_OPT_QSTATS
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_tx_qstat_name(
__in efx_nic_t *etp,
__in unsigned int id);
@@ -1781,21 +2123,89 @@ efx_tx_qdestroy(
#if EFSYS_OPT_FILTER
+#define EFX_ETHER_TYPE_IPV4 0x0800
+#define EFX_ETHER_TYPE_IPV6 0x86DD
+
+#define EFX_IPPROTO_TCP 6
+#define EFX_IPPROTO_UDP 17
+
typedef enum efx_filter_flag_e {
EFX_FILTER_FLAG_RX_RSS = 0x01, /* use RSS to spread across
* multiple queues */
EFX_FILTER_FLAG_RX_SCATTER = 0x02, /* enable RX scatter */
- EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04, /* MAC filter overrides
- * any matching IP filter */
+ EFX_FILTER_FLAG_RX_OVER_AUTO = 0x04, /* Override an automatic filter
+ * (priority EFX_FILTER_PRI_AUTO).
+ * May only be set by the filter
+ * implementation for each type.
+ * A removal request will
+ * restore the automatic filter
+ * in its place. */
+ EFX_FILTER_FLAG_RX = 0x08, /* Filter is for RX */
+ EFX_FILTER_FLAG_TX = 0x10, /* Filter is for TX */
} efx_filter_flag_t;
+typedef enum efx_filter_match_flags_e {
+ EFX_FILTER_MATCH_REM_HOST = 0x0001, /* Match by remote IP host
+ * address */
+ EFX_FILTER_MATCH_LOC_HOST = 0x0002, /* Match by local IP host
+ * address */
+ EFX_FILTER_MATCH_REM_MAC = 0x0004, /* Match by remote MAC address */
+ EFX_FILTER_MATCH_REM_PORT = 0x0008, /* Match by remote TCP/UDP port */
+ EFX_FILTER_MATCH_LOC_MAC = 0x0010, /* Match by remote TCP/UDP port */
+ EFX_FILTER_MATCH_LOC_PORT = 0x0020, /* Match by local TCP/UDP port */
+ EFX_FILTER_MATCH_ETHER_TYPE = 0x0040, /* Match by Ether-type */
+ EFX_FILTER_MATCH_INNER_VID = 0x0080, /* Match by inner VLAN ID */
+ EFX_FILTER_MATCH_OUTER_VID = 0x0100, /* Match by outer VLAN ID */
+ EFX_FILTER_MATCH_IP_PROTO = 0x0200, /* Match by IP transport
+ * protocol */
+ EFX_FILTER_MATCH_LOC_MAC_IG = 0x0400, /* Match by local MAC address
+ * I/G bit. Used for RX default
+ * unicast and multicast/
+ * broadcast filters. */
+} efx_filter_match_flags_t;
+
+typedef enum efx_filter_priority_s {
+ EFX_FILTER_PRI_HINT = 0, /* Performance hint */
+ EFX_FILTER_PRI_AUTO, /* Automatic filter based on device
+ * address list or hardware
+ * requirements. This may only be used
+ * by the filter implementation for
+ * each NIC type. */
+ EFX_FILTER_PRI_MANUAL, /* Manually configured filter */
+ EFX_FILTER_PRI_REQUIRED, /* Required for correct behaviour of the
+ * client (e.g. SR-IOV, HyperV VMQ etc.)
+ */
+} efx_filter_priority_t;
+
+/*
+ * FIXME: All these fields are assumed to be in little-endian byte order.
+ * It may be better for some to be big-endian. See bug42804.
+ */
+
typedef struct efx_filter_spec_s {
- uint8_t efs_type;
- uint8_t efs_flags;
- uint16_t efs_dmaq_id;
- uint32_t efs_dword[3];
+ uint32_t efs_match_flags:12;
+ uint32_t efs_priority:2;
+ uint32_t efs_flags:6;
+ uint32_t efs_dmaq_id:12;
+ uint32_t efs_rss_context;
+ uint16_t efs_outer_vid;
+ uint16_t efs_inner_vid;
+ uint8_t efs_loc_mac[EFX_MAC_ADDR_LEN];
+ uint8_t efs_rem_mac[EFX_MAC_ADDR_LEN];
+ uint16_t efs_ether_type;
+ uint8_t efs_ip_proto;
+ uint16_t efs_loc_port;
+ uint16_t efs_rem_port;
+ efx_oword_t efs_rem_host;
+ efx_oword_t efs_loc_host;
} efx_filter_spec_t;
+
+/* Default values for use in filter specifications */
+#define EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT 0xffffffff
+#define EFX_FILTER_SPEC_RX_DMAQ_ID_DROP 0xfff
+#define EFX_FILTER_SPEC_VID_UNSPEC 0xffff
+
extern __checkReturn int
efx_filter_init(
__in efx_nic_t *enp);
@@ -1805,115 +2215,82 @@ efx_filter_fini(
__in efx_nic_t *enp);
extern __checkReturn int
-efx_rx_filter_insert(
- __in efx_rxq_t *erp,
+efx_filter_insert(
+ __in efx_nic_t *enp,
__inout efx_filter_spec_t *spec);
extern __checkReturn int
-efx_rx_filter_remove(
- __in efx_rxq_t *erp,
+efx_filter_remove(
+ __in efx_nic_t *enp,
__inout efx_filter_spec_t *spec);
- void
+extern __checkReturn int
efx_filter_restore(
__in efx_nic_t *enp);
-extern void
-efx_filter_spec_rx_ipv4_tcp_full(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t src_ip,
- __in uint16_t src_tcp,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp);
+extern __checkReturn int
+efx_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length);
extern void
-efx_filter_spec_rx_ipv4_tcp_wild(
+efx_filter_spec_init_rx(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp);
+ __in efx_filter_priority_t priority,
+ __in efx_filter_flag_t flags,
+ __in efx_rxq_t *erp);
extern void
-efx_filter_spec_rx_ipv4_udp_full(
+efx_filter_spec_init_tx(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t src_ip,
- __in uint16_t src_udp,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp);
+ __in efx_txq_t *etp);
-extern void
-efx_filter_spec_rx_ipv4_udp_wild(
+extern __checkReturn int
+efx_filter_spec_set_ipv4_local(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp);
+ __in uint8_t proto,
+ __in uint32_t host,
+ __in uint16_t port);
-extern void
-efx_filter_spec_rx_mac_full(
+extern __checkReturn int
+efx_filter_spec_set_ipv4_full(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint16_t vlan_id,
- __in uint8_t *dest_mac);
+ __in uint8_t proto,
+ __in uint32_t lhost,
+ __in uint16_t lport,
+ __in uint32_t rhost,
+ __in uint16_t rport);
-extern void
-efx_filter_spec_rx_mac_wild(
+extern __checkReturn int
+efx_filter_spec_set_eth_local(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint8_t *dest_mac);
-
+ __in uint16_t vid,
+ __in const uint8_t *addr);
extern __checkReturn int
-efx_tx_filter_insert(
- __in efx_txq_t *etp,
+efx_filter_spec_set_uc_def(
__inout efx_filter_spec_t *spec);
extern __checkReturn int
-efx_tx_filter_remove(
- __in efx_txq_t *etp,
+efx_filter_spec_set_mc_def(
__inout efx_filter_spec_t *spec);
-extern void
-efx_filter_spec_tx_ipv4_tcp_full(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_tcp,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp);
-
-extern void
-efx_filter_spec_tx_ipv4_tcp_wild(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_tcp);
-
-extern void
-efx_filter_spec_tx_ipv4_udp_full(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_udp,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp);
-
-extern void
-efx_filter_spec_tx_ipv4_udp_wild(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_udp);
+#endif /* EFSYS_OPT_FILTER */
-extern void
-efx_filter_spec_tx_mac_full(
- __inout efx_filter_spec_t *spec,
- __in uint16_t vlan_id,
- __in uint8_t *src_mac);
+/* HASH */
-extern void
-efx_filter_spec_tx_mac_wild(
- __inout efx_filter_spec_t *spec,
- __in uint8_t *src_mac);
+extern __checkReturn uint32_t
+efx_hash_dwords(
+ __in_ecount(count) uint32_t const *input,
+ __in size_t count,
+ __in uint32_t init);
-#endif /* EFSYS_OPT_FILTER */
+extern __checkReturn uint32_t
+efx_hash_bytes(
+ __in_ecount(length) uint8_t const *input,
+ __in size_t length,
+ __in uint32_t init);
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/efx_bootcfg.c b/sys/dev/sfxge/common/efx_bootcfg.c
index d770a5c3cad0..330f69dbd5a9 100644
--- a/sys/dev/sfxge/common/efx_bootcfg.c
+++ b/sys/dev/sfxge/common/efx_bootcfg.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -64,7 +69,7 @@ efx_bootcfg_verify(
__in efx_nic_t *enp,
__in_bcount(size) caddr_t data,
__in size_t size,
- __out size_t *usedp)
+ __out_opt size_t *usedp)
{
size_t offset = 0;
size_t used = 0;
diff --git a/sys/dev/sfxge/common/efx_check.h b/sys/dev/sfxge/common/efx_check.h
new file mode 100644
index 000000000000..9e590a41d967
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_check.h
@@ -0,0 +1,388 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_EFX_CHECK_H
+#define _SYS_EFX_CHECK_H
+
+#include "efsys.h"
+
+/*
+ * Check that the efsys.h header in client code has a valid combination of
+ * EFSYS_OPT_xxx options.
+ *
+ * NOTE: Keep checks for obsolete options here to ensure that they are removed
+ * from client code (and do not reappear in merges from other branches).
+ */
+
+/* Support NVRAM based boot config */
+#if EFSYS_OPT_BOOTCFG
+# if !EFSYS_OPT_NVRAM
+# error "BOOTCFG requires NVRAM"
+# endif
+#endif /* EFSYS_OPT_BOOTCFG */
+
+/* Verify chip implements accessed registers */
+#if EFSYS_OPT_CHECK_REG
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "CHECK_REG requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_CHECK_REG */
+
+/* Decode fatal errors */
+#if EFSYS_OPT_DECODE_INTR_FATAL
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# if EFSYS_OPT_HUNTINGTON
+# error "INTR_FATAL not supported on HUNTINGTON"
+# endif
+# error "INTR_FATAL requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_DECODE_INTR_FATAL */
+
+/* Support diagnostic hardware tests */
+#if EFSYS_OPT_DIAG
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "DIAG requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_DIAG */
+
+/* Support optimized EVQ data access */
+#if EFSYS_OPT_EV_PREFETCH
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "EV_PREFETCH requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_EV_PREFETCH */
+
+/* Support overriding the NVRAM and VPD configuration */
+#if EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE
+# if !EFSYS_OPT_FALCON
+# error "FALCON_NIC_CFG_OVERRIDE requires FALCON"
+# endif
+#endif /* EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE */
+
+/* Support hardware packet filters */
+#if EFSYS_OPT_FILTER
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "FILTER requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_FILTER */
+
+#if EFSYS_OPT_HUNTINGTON
+# if !EFSYS_OPT_FILTER
+# error "HUNTINGTON requires FILTER"
+# endif
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+/* Support hardware loopback modes */
+#if EFSYS_OPT_LOOPBACK
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "LOOPBACK requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_LOOPBACK */
+
+/* Support Falcon GMAC */
+#if EFSYS_OPT_MAC_FALCON_GMAC
+# if !EFSYS_OPT_FALCON
+# error "MAC_FALCON_GMAC requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MAC_FALCON_GMAC */
+
+/* Support Falcon XMAC */
+#if EFSYS_OPT_MAC_FALCON_XMAC
+# if !EFSYS_OPT_FALCON
+# error "MAC_FALCON_XMAC requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MAC_FALCON_XMAC */
+
+/* Support MAC statistics */
+#if EFSYS_OPT_MAC_STATS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "MAC_STATS requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MAC_STATS */
+
+/* Support management controller messages */
+#if EFSYS_OPT_MCDI
+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# if EFSYS_OPT_FALCON
+# error "MCDI not supported on FALCON"
+# endif
+# error "MCDI requires SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MCDI */
+
+#if EFSYS_OPT_SIENA && !EFSYS_OPT_MCDI
+# error "SIENA requires MCDI"
+#endif
+#if EFSYS_OPT_HUNTINGTON && !EFSYS_OPT_MCDI
+# error "HUNTINGTON requires MCDI"
+#endif
+
+/* Support LM87 monitor */
+#if EFSYS_OPT_MON_LM87
+# if !EFSYS_OPT_FALCON
+# error "MON_LM87 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MON_LM87 */
+
+/* Support MAX6647 monitor */
+#if EFSYS_OPT_MON_MAX6647
+# if !EFSYS_OPT_FALCON
+# error "MON_MAX6647 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MON_MAX6647 */
+
+/* Support null monitor */
+#if EFSYS_OPT_MON_NULL
+# if !EFSYS_OPT_FALCON
+# error "MON_NULL requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MON_NULL */
+
+/* Support Siena monitor */
+#ifdef EFSYS_OPT_MON_SIENA
+# error "MON_SIENA is obsolete use MON_MCDI"
+#endif /* EFSYS_OPT_MON_SIENA*/
+
+/* Support Huntington monitor */
+#ifdef EFSYS_OPT_MON_HUNTINGTON
+# error "MON_HUNTINGTON is obsolete use MON_MCDI"
+#endif /* EFSYS_OPT_MON_HUNTINGTON*/
+
+/* Support monitor statistics (voltage/temperature) */
+#if EFSYS_OPT_MON_STATS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "MON_STATS requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MON_STATS */
+
+/* Support Monitor via mcdi */
+#if EFSYS_OPT_MON_MCDI
+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "MON_MCDI requires SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MON_MCDI*/
+
+/* Support printable names for statistics */
+#if EFSYS_OPT_NAMES
+# if !(EFSYS_OPT_LOOPBACK || EFSYS_OPT_MAC_STATS || EFSYS_OPT_MCDI || \
+ EFSYS_MON_STATS || EFSYS_OPT_PHY_PROPS || EFSYS_OPT_PHY_STATS || \
+ EFSYS_OPT_QSTATS)
+# error "NAMES requires LOOPBACK or xxxSTATS or MCDI or PHY_PROPS"
+# endif
+#endif /* EFSYS_OPT_NAMES */
+
+/* Support non volatile configuration */
+#if EFSYS_OPT_NVRAM
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "NVRAM requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_NVRAM */
+
+/* Support Falcon bootrom */
+#if EFSYS_OPT_NVRAM_FALCON_BOOTROM
+# if !EFSYS_OPT_NVRAM
+# error "NVRAM_FALCON_BOOTROM requires NVRAM"
+# endif
+# if !EFSYS_OPT_FALCON
+# error "NVRAM_FALCON_BOOTROM requires FALCON"
+# endif
+#endif /* EFSYS_OPT_NVRAM_FALCON_BOOTROM */
+
+/* Support NVRAM config for SFT9001 */
+#if EFSYS_OPT_NVRAM_SFT9001
+# if !EFSYS_OPT_NVRAM
+# error "NVRAM_SFT9001 requires NVRAM"
+# endif
+# if !EFSYS_OPT_FALCON
+# error "NVRAM_SFT9001 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_NVRAM_SFT9001 */
+
+/* Support NVRAM config for SFX7101 */
+#if EFSYS_OPT_NVRAM_SFX7101
+# if !EFSYS_OPT_NVRAM
+# error "NVRAM_SFX7101 requires NVRAM"
+# endif
+# if !EFSYS_OPT_FALCON
+# error "NVRAM_SFX7101 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_NVRAM_SFX7101 */
+
+/* Support PCIe interface tuning */
+#if EFSYS_OPT_PCIE_TUNE
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PCIE_TUNE requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PCIE_TUNE */
+
+/* Support PHY BIST diagnostics */
+#if EFSYS_OPT_PHY_BIST
+# error "PHY_BIST is obsolete. It has been replaced by the BIST option."
+#endif /* EFSYS_OPT_PHY_BIST */
+
+/* Support PHY flags */
+#if EFSYS_OPT_PHY_FLAGS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PHY_FLAGS requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_FLAGS */
+
+/* Support for PHY LED control */
+#if EFSYS_OPT_PHY_LED_CONTROL
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PHY_LED_CONTROL requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
+/* Support NULL PHY */
+#if EFSYS_OPT_PHY_NULL
+# if !EFSYS_OPT_FALCON
+# error "PHY_NULL requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_NULL */
+
+/* Obsolete option */
+#ifdef EFSYS_OPT_PHY_PM8358
+# error "EFSYS_OPT_PHY_PM8358 is obsolete and is not supported."
+#endif
+
+/* Support PHY properties */
+#if EFSYS_OPT_PHY_PROPS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PHY_PROPS requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+/* Support QT2022C2 PHY */
+#if EFSYS_OPT_PHY_QT2022C2
+# if !EFSYS_OPT_FALCON
+# error "PHY_QT2022C2 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_QT2022C2 */
+
+/* Support QT2025C PHY (Wakefield NIC) */
+#if EFSYS_OPT_PHY_QT2025C
+# if !EFSYS_OPT_FALCON
+# error "PHY_QT2025C requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_QT2025C */
+
+/* Support SFT9001 PHY (Starbolt NIC) */
+#if EFSYS_OPT_PHY_SFT9001
+# if !EFSYS_OPT_FALCON
+# error "PHY_SFT9001 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_SFT9001 */
+
+/* Support SFX7101 PHY (SFE4001 NIC) */
+#if EFSYS_OPT_PHY_SFX7101
+# if !EFSYS_OPT_FALCON
+# error "PHY_SFX7101 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_SFX7101 */
+
+/* Support PHY statistics */
+#if EFSYS_OPT_PHY_STATS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PHY_STATS requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_STATS */
+
+/* Support TXC43128 PHY (SFE4003 NIC) */
+#if EFSYS_OPT_PHY_TXC43128
+# if !EFSYS_OPT_FALCON
+# error "PHY_TXC43128 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_TXC43128 */
+
+/* Support EVQ/RXQ/TXQ statistics */
+#if EFSYS_OPT_QSTATS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "QSTATS requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_QSTATS */
+
+/* Support receive header split */
+#if EFSYS_OPT_RX_HDR_SPLIT
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "RX_HDR_SPLIT requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+/* Support receive scaling (RSS) */
+#if EFSYS_OPT_RX_SCALE
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "RX_SCALE requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_RX_SCALE */
+
+/* Support receive scatter DMA */
+#if EFSYS_OPT_RX_SCATTER
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "RX_SCATTER requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+/* Obsolete option */
+#ifdef EFSYS_OPT_STAT_NAME
+# error "EFSYS_OPT_STAT_NAME is obsolete (replaced by EFSYS_OPT_NAMES)."
+#endif
+
+/* Support PCI Vital Product Data (VPD) */
+#if EFSYS_OPT_VPD
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "VPD requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_VPD */
+
+/* Support Wake on LAN */
+#if EFSYS_OPT_WOL
+# if !EFSYS_OPT_SIENA
+# error "WOL requires SIENA"
+# endif
+#endif /* EFSYS_OPT_WOL */
+
+/* Support calculating multicast pktfilter in common code */
+#if EFSYS_OPT_MCAST_FILTER_LIST
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "MCAST_FILTER_LIST requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MCAST_FILTER_LIST */
+
+/* Support BIST */
+#if EFSYS_OPT_BIST
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "BIST requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_BIST */
+
+#endif /* _SYS_EFX_CHECK_H */
diff --git a/sys/dev/sfxge/common/efx_crc32.c b/sys/dev/sfxge/common/efx_crc32.c
new file mode 100644
index 000000000000..7e4cfc451336
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_crc32.c
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2013-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_impl.h"
+
+/*
+ * Precomputed table for computing IEEE 802.3 CRC32
+ * with polynomial 0x04c11db7 (bit-reversed 0xedb88320)
+ */
+
+static const uint32_t crc32_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/* Calculate the IEEE 802.3 CRC32 of a MAC addr */
+ __checkReturn uint32_t
+efx_crc32_calculate(
+ __in uint32_t crc_init,
+ __in_ecount(length) uint8_t const *input,
+ __in int length)
+{
+ int index;
+ uint32_t crc = crc_init;
+
+ for (index = 0; index < length; index++) {
+ uint32_t data = *(input++);
+ crc = (crc >> 8) ^ crc32_table[(crc ^ data) & 0xff];
+ }
+
+ return (crc);
+}
diff --git a/sys/dev/sfxge/common/efx_ev.c b/sys/dev/sfxge/common/efx_ev.c
index fff7803a13d1..9669fc450c2c 100644
--- a/sys/dev/sfxge/common/efx_ev.c
+++ b/sys/dev/sfxge/common/efx_ev.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -31,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "efx_types.h"
#include "efx_regs.h"
#include "efx_impl.h"
+#include "mcdi_mon.h"
#if EFSYS_OPT_QSTATS
#define EFX_EV_QSTAT_INCR(_eep, _stat) \
@@ -42,11 +48,118 @@ __FBSDID("$FreeBSD$");
#define EFX_EV_QSTAT_INCR(_eep, _stat)
#endif
+#define EFX_EV_PRESENT(_qword) \
+ (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff && \
+ EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff)
+
+
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_ev_init(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_ev_fini(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_ev_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in efx_evq_t *eep);
+
+static void
+falconsiena_ev_qdestroy(
+ __in efx_evq_t *eep);
+
+static __checkReturn int
+falconsiena_ev_qprime(
+ __in efx_evq_t *eep,
+ __in unsigned int count);
+
+static void
+falconsiena_ev_qpoll(
+ __in efx_evq_t *eep,
+ __inout unsigned int *countp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static void
+falconsiena_ev_qpost(
+ __in efx_evq_t *eep,
+ __in uint16_t data);
+
+static __checkReturn int
+falconsiena_ev_qmoderate(
+ __in efx_evq_t *eep,
+ __in unsigned int us);
+
+#if EFSYS_OPT_QSTATS
+static void
+falconsiena_ev_qstats_update(
+ __in efx_evq_t *eep,
+ __inout_ecount(EV_NQSTATS) efsys_stat_t *stat);
+
+#endif
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_FALCON
+static efx_ev_ops_t __efx_ev_falcon_ops = {
+ falconsiena_ev_init, /* eevo_init */
+ falconsiena_ev_fini, /* eevo_fini */
+ falconsiena_ev_qcreate, /* eevo_qcreate */
+ falconsiena_ev_qdestroy, /* eevo_qdestroy */
+ falconsiena_ev_qprime, /* eevo_qprime */
+ falconsiena_ev_qpost, /* eevo_qpost */
+ falconsiena_ev_qmoderate, /* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+ falconsiena_ev_qstats_update, /* eevo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_ev_ops_t __efx_ev_siena_ops = {
+ falconsiena_ev_init, /* eevo_init */
+ falconsiena_ev_fini, /* eevo_fini */
+ falconsiena_ev_qcreate, /* eevo_qcreate */
+ falconsiena_ev_qdestroy, /* eevo_qdestroy */
+ falconsiena_ev_qprime, /* eevo_qprime */
+ falconsiena_ev_qpost, /* eevo_qpost */
+ falconsiena_ev_qmoderate, /* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+ falconsiena_ev_qstats_update, /* eevo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_ev_ops_t __efx_ev_hunt_ops = {
+ hunt_ev_init, /* eevo_init */
+ hunt_ev_fini, /* eevo_fini */
+ hunt_ev_qcreate, /* eevo_qcreate */
+ hunt_ev_qdestroy, /* eevo_qdestroy */
+ hunt_ev_qprime, /* eevo_qprime */
+ hunt_ev_qpost, /* eevo_qpost */
+ hunt_ev_qmoderate, /* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+ hunt_ev_qstats_update, /* eevo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+
__checkReturn int
efx_ev_init(
__in efx_nic_t *enp)
{
- efx_oword_t oword;
+ efx_ev_ops_t *eevop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -57,8 +170,290 @@ efx_ev_init(
goto fail1;
}
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ eevop = (efx_ev_ops_t *)&__efx_ev_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ eevop = (efx_ev_ops_t *)&__efx_ev_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ eevop = (efx_ev_ops_t *)&__efx_ev_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
+ if ((rc = eevop->eevo_init(enp)) != 0)
+ goto fail2;
+
+ enp->en_eevop = eevop;
+ enp->en_mod_flags |= EFX_MOD_EV;
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ enp->en_eevop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_EV;
+ return (rc);
+}
+
+ void
+efx_ev_fini(
+ __in efx_nic_t *enp)
+{
+ efx_ev_ops_t *eevop = enp->en_eevop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
+ EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
+ EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
+ EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
+
+ eevop->eevo_fini(enp);
+
+ enp->en_eevop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_EV;
+}
+
+
+ __checkReturn int
+efx_ev_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __deref_out efx_evq_t **eepp)
+{
+ efx_ev_ops_t *eevop = enp->en_eevop;
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_evq_t *eep;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
+
+ EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <, encp->enc_evq_limit);
+
+ /* Allocate an EVQ object */
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep);
+ if (eep == NULL) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+
+ eep->ee_magic = EFX_EVQ_MAGIC;
+ eep->ee_enp = enp;
+ eep->ee_index = index;
+ eep->ee_mask = n - 1;
+ eep->ee_esmp = esmp;
+
+ if ((rc = eevop->eevo_qcreate(enp, index, esmp, n, id, eep)) != 0)
+ goto fail2;
+
+ enp->en_ev_qcount++;
+ *eepp = eep;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+efx_ev_qdestroy(
+ __in efx_evq_t *eep)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_ev_ops_t *eevop = enp->en_eevop;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ EFSYS_ASSERT(enp->en_ev_qcount != 0);
+ --enp->en_ev_qcount;
+
+ eevop->eevo_qdestroy(eep);
+
+ /* Free the EVQ object */
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
+}
+
+ __checkReturn int
+efx_ev_qprime(
+ __in efx_evq_t *eep,
+ __in unsigned int count)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_ev_ops_t *eevop = enp->en_eevop;
+ int rc;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ if (!(enp->en_mod_flags & EFX_MOD_INTR)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if ((rc = eevop->eevo_qprime(eep, count)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ __checkReturn boolean_t
+efx_ev_qpending(
+ __in efx_evq_t *eep,
+ __in unsigned int count)
+{
+ size_t offset;
+ efx_qword_t qword;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
+ EFSYS_MEM_READQ(eep->ee_esmp, offset, &qword);
+
+ return (EFX_EV_PRESENT(qword));
+}
+
+#if EFSYS_OPT_EV_PREFETCH
+
+ void
+efx_ev_qprefetch(
+ __in efx_evq_t *eep,
+ __in unsigned int count)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ unsigned int offset;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
+ EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
+}
+
+#endif /* EFSYS_OPT_EV_PREFETCH */
+
+ void
+efx_ev_qpoll(
+ __in efx_evq_t *eep,
+ __inout unsigned int *countp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ /*
+ * FIXME: Huntington will require support for hardware event batching
+ * and merging, which will need a different ev_qpoll implementation.
+ *
+ * Without those features the Falcon/Siena code can be used unchanged.
+ */
+ EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_LBN == FSF_AZ_EV_CODE_LBN);
+ EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_WIDTH == FSF_AZ_EV_CODE_WIDTH);
+
+ EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_RX_EV == FSE_AZ_EV_CODE_RX_EV);
+ EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_TX_EV == FSE_AZ_EV_CODE_TX_EV);
+ EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRIVER_EV == FSE_AZ_EV_CODE_DRIVER_EV);
+ EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRV_GEN_EV ==
+ FSE_AZ_EV_CODE_DRV_GEN_EV);
+#if EFSYS_OPT_MCDI
+ EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_MCDI_EV ==
+ FSE_AZ_EV_CODE_MCDI_EVRESPONSE);
+#endif
+ falconsiena_ev_qpoll(eep, countp, eecp, arg);
+}
+
+ void
+efx_ev_qpost(
+ __in efx_evq_t *eep,
+ __in uint16_t data)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_ev_ops_t *eevop = enp->en_eevop;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ EFSYS_ASSERT(eevop != NULL &&
+ eevop->eevo_qpost != NULL);
+
+ eevop->eevo_qpost(eep, data);
+}
+
+ __checkReturn int
+efx_ev_qmoderate(
+ __in efx_evq_t *eep,
+ __in unsigned int us)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_ev_ops_t *eevop = enp->en_eevop;
+ int rc;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ if ((rc = eevop->eevo_qmoderate(eep, us)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+#if EFSYS_OPT_QSTATS
+ void
+efx_ev_qstats_update(
+ __in efx_evq_t *eep,
+ __inout_ecount(EV_NQSTATS) efsys_stat_t *stat)
+
+{ efx_nic_t *enp = eep->ee_enp;
+ efx_ev_ops_t *eevop = enp->en_eevop;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ eevop->eevo_qstats_update(eep, stat);
+}
+
+#endif /* EFSYS_OPT_QSTATS */
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_ev_init(
+ __in efx_nic_t *enp)
+{
+ efx_oword_t oword;
+
/*
* Program the event queue for receive and transmit queue
* flush events.
@@ -67,17 +462,12 @@ efx_ev_init(
EFX_SET_OWORD_FIELD(oword, FRF_AZ_FLS_EVQ_ID, 0);
EFX_BAR_WRITEO(enp, FR_AZ_DP_CTRL_REG, &oword);
- enp->en_mod_flags |= EFX_MOD_EV;
return (0);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
}
static __checkReturn boolean_t
-efx_ev_rx_not_ok(
+falconsiena_ev_rx_not_ok(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in uint32_t label,
@@ -167,7 +557,7 @@ efx_ev_rx_not_ok(
}
static __checkReturn boolean_t
-efx_ev_rx(
+falconsiena_ev_rx(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -264,7 +654,7 @@ efx_ev_rx(
/* Detect errors included in the FSF_AZ_RX_EV_PKT_OK indication */
if (!ok) {
- ignore = efx_ev_rx_not_ok(eep, eqp, label, id, &flags);
+ ignore = falconsiena_ev_rx_not_ok(eep, eqp, label, id, &flags);
if (ignore) {
EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id,
uint32_t, size, uint16_t, flags);
@@ -323,7 +713,7 @@ efx_ev_rx(
}
static __checkReturn boolean_t
-efx_ev_tx(
+falconsiena_ev_tx(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -370,7 +760,7 @@ efx_ev_tx(
}
static __checkReturn boolean_t
-efx_ev_global(
+falconsiena_ev_global(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -396,7 +786,7 @@ efx_ev_global(
}
static __checkReturn boolean_t
-efx_ev_driver(
+falconsiena_ev_driver(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -437,7 +827,8 @@ efx_ev_driver(
EFSYS_PROBE1(rx_descq_fls_failed, uint32_t, rxq_index);
- should_abort = eecp->eec_rxq_flush_failed(arg, rxq_index);
+ should_abort = eecp->eec_rxq_flush_failed(arg,
+ rxq_index);
} else {
EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
@@ -524,7 +915,7 @@ efx_ev_driver(
}
static __checkReturn boolean_t
-efx_ev_drv_gen(
+falconsiena_ev_drv_gen(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -552,7 +943,7 @@ efx_ev_drv_gen(
#if EFSYS_OPT_MCDI
static __checkReturn boolean_t
-efx_ev_mcdi(
+falconsiena_ev_mcdi(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -583,9 +974,9 @@ efx_ev_mcdi(
case MCDI_EVENT_CODE_CMDDONE:
efx_mcdi_ev_cpl(enp,
- MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
- MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
- MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
+ MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
+ MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
+ MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
break;
case MCDI_EVENT_CODE_LINKCHANGE: {
@@ -601,7 +992,7 @@ efx_ev_mcdi(
efx_mon_stat_value_t value;
int rc;
- if ((rc = siena_mon_ev(enp, eqp, &id, &value)) == 0)
+ if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0)
should_abort = eecp->eec_monitor(arg, id, value);
else if (rc == ENOTSUP) {
should_abort = eecp->eec_exception(arg,
@@ -656,22 +1047,14 @@ out:
#endif /* EFSYS_OPT_MCDI */
- __checkReturn int
-efx_ev_qprime(
+static __checkReturn int
+falconsiena_ev_qprime(
__in efx_evq_t *eep,
__in unsigned int count)
{
efx_nic_t *enp = eep->ee_enp;
uint32_t rptr;
efx_dword_t dword;
- int rc;
-
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
- if (!(enp->en_mod_flags & EFX_MOD_INTR)) {
- rc = EINVAL;
- goto fail1;
- }
rptr = count & eep->ee_mask;
@@ -681,55 +1064,12 @@ efx_ev_qprime(
&dword, B_FALSE);
return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
- __checkReturn boolean_t
-efx_ev_qpending(
- __in efx_evq_t *eep,
- __in unsigned int count)
-{
- size_t offset;
- efx_qword_t qword;
-
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
- offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
- EFSYS_MEM_READQ(eep->ee_esmp, offset, &qword);
-
- return (EFX_QWORD_FIELD(qword, EFX_DWORD_0) != 0xffffffff &&
- EFX_QWORD_FIELD(qword, EFX_DWORD_1) != 0xffffffff);
-}
-
-#if EFSYS_OPT_EV_PREFETCH
-
- void
-efx_ev_qprefetch(
- __in efx_evq_t *eep,
- __in unsigned int count)
-{
- unsigned int offset;
-
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
- offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
- EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
}
-#endif /* EFSYS_OPT_EV_PREFETCH */
-
#define EFX_EV_BATCH 8
-#define EFX_EV_PRESENT(_qword) \
- (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff && \
- EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff)
-
- void
-efx_ev_qpoll(
+static void
+falconsiena_ev_qpoll(
__in efx_evq_t *eep,
__inout unsigned int *countp,
__in const efx_ev_callbacks_t *eecp,
@@ -742,7 +1082,6 @@ efx_ev_qpoll(
unsigned int index;
size_t offset;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
EFSYS_ASSERT(countp != NULL);
EFSYS_ASSERT(eecp != NULL);
@@ -778,7 +1117,6 @@ efx_ev_qpoll(
for (index = 0; index < total; ++index) {
boolean_t should_abort;
uint32_t code;
- efx_ev_handler_t handler;
#if EFSYS_OPT_EV_PREFETCH
/* Prefetch if we've now reached the batch period */
@@ -794,9 +1132,49 @@ efx_ev_qpoll(
EFX_EV_QSTAT_INCR(eep, EV_ALL);
code = EFX_QWORD_FIELD(ev[index], FSF_AZ_EV_CODE);
- handler = eep->ee_handler[code];
- EFSYS_ASSERT(handler != NULL);
- should_abort = handler(eep, &(ev[index]), eecp, arg);
+ switch (code) {
+ case FSE_AZ_EV_CODE_RX_EV:
+ should_abort = eep->ee_rx(eep,
+ &(ev[index]), eecp, arg);
+ break;
+ case FSE_AZ_EV_CODE_TX_EV:
+ should_abort = eep->ee_tx(eep,
+ &(ev[index]), eecp, arg);
+ break;
+ case FSE_AZ_EV_CODE_DRIVER_EV:
+ should_abort = eep->ee_driver(eep,
+ &(ev[index]), eecp, arg);
+ break;
+ case FSE_AZ_EV_CODE_DRV_GEN_EV:
+ should_abort = eep->ee_drv_gen(eep,
+ &(ev[index]), eecp, arg);
+ break;
+#if EFSYS_OPT_MCDI
+ case FSE_AZ_EV_CODE_MCDI_EVRESPONSE:
+ should_abort = eep->ee_mcdi(eep,
+ &(ev[index]), eecp, arg);
+ break;
+#endif
+ case FSE_AZ_EV_CODE_GLOBAL_EV:
+ if (eep->ee_global) {
+ should_abort = eep->ee_global(eep,
+ &(ev[index]), eecp, arg);
+ break;
+ }
+ /* else fallthrough */
+ default:
+ EFSYS_PROBE3(bad_event,
+ unsigned int, eep->ee_index,
+ uint32_t,
+ EFX_QWORD_FIELD(ev[index], EFX_DWORD_1),
+ uint32_t,
+ EFX_QWORD_FIELD(ev[index], EFX_DWORD_0));
+
+ EFSYS_ASSERT(eecp->eec_exception != NULL);
+ (void) eecp->eec_exception(arg,
+ EFX_EXCEPTION_EV_ERROR, code);
+ should_abort = B_TRUE;
+ }
if (should_abort) {
/* Ignore subsequent events */
total = index + 1;
@@ -823,8 +1201,8 @@ efx_ev_qpoll(
*countp = count;
}
- void
-efx_ev_qpost(
+static void
+falconsiena_ev_qpost(
__in efx_evq_t *eep,
__in uint16_t data)
{
@@ -832,8 +1210,6 @@ efx_ev_qpost(
efx_qword_t ev;
efx_oword_t oword;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
EFX_POPULATE_QWORD_2(ev, FSF_AZ_EV_CODE, FSE_AZ_EV_CODE_DRV_GEN_EV,
FSF_AZ_EV_DATA_DW0, (uint32_t)data);
@@ -844,8 +1220,8 @@ efx_ev_qpost(
EFX_BAR_WRITEO(enp, FR_AZ_DRV_EV_REG, &oword);
}
- __checkReturn int
-efx_ev_qmoderate(
+static __checkReturn int
+falconsiena_ev_qmoderate(
__in efx_evq_t *eep,
__in unsigned int us)
{
@@ -855,8 +1231,6 @@ efx_ev_qmoderate(
efx_dword_t dword;
int rc;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
if (us > encp->enc_evq_timer_max_us) {
rc = EINVAL;
goto fail1;
@@ -905,27 +1279,24 @@ fail1:
return (rc);
}
- __checkReturn int
-efx_ev_qcreate(
+static __checkReturn int
+falconsiena_ev_qcreate(
__in efx_nic_t *enp,
__in unsigned int index,
__in efsys_mem_t *esmp,
__in size_t n,
__in uint32_t id,
- __deref_out efx_evq_t **eepp)
+ __in efx_evq_t *eep)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
uint32_t size;
- efx_evq_t *eep;
efx_oword_t oword;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
+ EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
+ EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
- EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <, encp->enc_evq_limit);
-
- if (!ISP2(n) || !(n & EFX_EVQ_NEVS_MASK)) {
+ if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {
rc = EINVAL;
goto fail1;
}
@@ -949,46 +1320,29 @@ efx_ev_qcreate(
goto fail4;
}
- /* Allocate an EVQ object */
- EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep);
- if (eep == NULL) {
- rc = ENOMEM;
- goto fail5;
- }
-
- eep->ee_magic = EFX_EVQ_MAGIC;
- eep->ee_enp = enp;
- eep->ee_index = index;
- eep->ee_mask = n - 1;
- eep->ee_esmp = esmp;
-
/* Set up the handler table */
- eep->ee_handler[FSE_AZ_EV_CODE_RX_EV] = efx_ev_rx;
- eep->ee_handler[FSE_AZ_EV_CODE_TX_EV] = efx_ev_tx;
- eep->ee_handler[FSE_AZ_EV_CODE_DRIVER_EV] = efx_ev_driver;
- eep->ee_handler[FSE_AZ_EV_CODE_GLOBAL_EV] = efx_ev_global;
- eep->ee_handler[FSE_AZ_EV_CODE_DRV_GEN_EV] = efx_ev_drv_gen;
+ eep->ee_rx = falconsiena_ev_rx;
+ eep->ee_tx = falconsiena_ev_tx;
+ eep->ee_driver = falconsiena_ev_driver;
+ eep->ee_global = falconsiena_ev_global;
+ eep->ee_drv_gen = falconsiena_ev_drv_gen;
#if EFSYS_OPT_MCDI
- eep->ee_handler[FSE_AZ_EV_CODE_MCDI_EVRESPONSE] = efx_ev_mcdi;
+ eep->ee_mcdi = falconsiena_ev_mcdi;
#endif /* EFSYS_OPT_MCDI */
/* Set up the new event queue */
if (enp->en_family != EFX_FAMILY_FALCON) {
EFX_POPULATE_OWORD_1(oword, FRF_CZ_TIMER_Q_EN, 1);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword, B_TRUE);
}
EFX_POPULATE_OWORD_3(oword, FRF_AZ_EVQ_EN, 1, FRF_AZ_EVQ_SIZE, size,
FRF_AZ_EVQ_BUF_BASE_ID, id);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword, B_TRUE);
- enp->en_ev_qcount++;
- *eepp = eep;
return (0);
-fail5:
- EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
#if EFSYS_OPT_RX_SCALE
@@ -1003,14 +1357,15 @@ fail1:
return (rc);
}
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
#if EFSYS_OPT_QSTATS
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED EfxEventQueueStatNamesBlock 67e9bdcd920059bd */
-static const char __cs * __cs __efx_ev_qstat_name[] = {
+/* START MKCONFIG GENERATED EfxEventQueueStatNamesBlock b693ddf85aee1bfd */
+static const char *__efx_ev_qstat_name[] = {
"all",
"rx",
"rx_ok",
- "rx_recovery",
"rx_frm_trunc",
"rx_tobe_disc",
"rx_pause_frm_err",
@@ -1028,16 +1383,14 @@ static const char __cs * __cs __efx_ev_qstat_name[] = {
"rx_other_ipv4",
"rx_other_ipv6",
"rx_non_ip",
- "rx_overrun",
+ "rx_batch",
"tx",
"tx_wq_ff_full",
"tx_pkt_err",
"tx_pkt_too_big",
"tx_unexpected",
"global",
- "global_phy",
"global_mnt",
- "global_rx_recovery",
"driver",
"driver_srm_upd_done",
"driver_tx_descq_fls_done",
@@ -1050,7 +1403,7 @@ static const char __cs * __cs __efx_ev_qstat_name[] = {
};
/* END MKCONFIG GENERATED EfxEventQueueStatNamesBlock */
- const char __cs *
+ const char *
efx_ev_qstat_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -1063,16 +1416,16 @@ efx_ev_qstat_name(
#endif /* EFSYS_OPT_NAMES */
#endif /* EFSYS_OPT_QSTATS */
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
#if EFSYS_OPT_QSTATS
- void
-efx_ev_qstats_update(
+static void
+falconsiena_ev_qstats_update(
__in efx_evq_t *eep,
__inout_ecount(EV_NQSTATS) efsys_stat_t *stat)
{
unsigned int id;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
for (id = 0; id < EV_NQSTATS; id++) {
efsys_stat_t *essp = &stat[id];
@@ -1082,44 +1435,31 @@ efx_ev_qstats_update(
}
#endif /* EFSYS_OPT_QSTATS */
- void
-efx_ev_qdestroy(
+static void
+falconsiena_ev_qdestroy(
__in efx_evq_t *eep)
{
efx_nic_t *enp = eep->ee_enp;
efx_oword_t oword;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
- EFSYS_ASSERT(enp->en_ev_qcount != 0);
- --enp->en_ev_qcount;
-
/* Purge event queue */
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL,
- eep->ee_index, &oword);
+ eep->ee_index, &oword, B_TRUE);
if (enp->en_family != EFX_FAMILY_FALCON) {
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL,
- eep->ee_index, &oword);
+ eep->ee_index, &oword, B_TRUE);
}
-
- /* Free the EVQ object */
- EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
}
- void
-efx_ev_fini(
+static void
+falconsiena_ev_fini(
__in efx_nic_t *enp)
{
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
- EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
- EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
- EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
-
- enp->en_mod_flags &= ~EFX_MOD_EV;
+ _NOTE(ARGUNUSED(enp))
}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_filter.c b/sys/dev/sfxge/common/efx_filter.c
index e8455db47c32..7ae7ea583e8f 100644
--- a/sys/dev/sfxge/common/efx_filter.c
+++ b/sys/dev/sfxge/common/efx_filter.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -35,24 +40,569 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_FILTER
-/* "Fudge factors" - difference between programmed value and actual depth.
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_filter_init(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_filter_fini(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_filter_restore(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_filter_add(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec,
+ __in boolean_t may_replace);
+
+static __checkReturn int
+falconsiena_filter_delete(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec);
+
+static __checkReturn int
+falconsiena_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length);
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_FALCON
+static efx_filter_ops_t __efx_filter_falcon_ops = {
+ falconsiena_filter_init, /* efo_init */
+ falconsiena_filter_fini, /* efo_fini */
+ falconsiena_filter_restore, /* efo_restore */
+ falconsiena_filter_add, /* efo_add */
+ falconsiena_filter_delete, /* efo_delete */
+ falconsiena_filter_supported_filters, /* efo_supported_filters */
+ NULL, /* efo_reconfigure */
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_filter_ops_t __efx_filter_siena_ops = {
+ falconsiena_filter_init, /* efo_init */
+ falconsiena_filter_fini, /* efo_fini */
+ falconsiena_filter_restore, /* efo_restore */
+ falconsiena_filter_add, /* efo_add */
+ falconsiena_filter_delete, /* efo_delete */
+ falconsiena_filter_supported_filters, /* efo_supported_filters */
+ NULL, /* efo_reconfigure */
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_filter_ops_t __efx_filter_hunt_ops = {
+ hunt_filter_init, /* efo_init */
+ hunt_filter_fini, /* efo_fini */
+ hunt_filter_restore, /* efo_restore */
+ hunt_filter_add, /* efo_add */
+ hunt_filter_delete, /* efo_delete */
+ hunt_filter_supported_filters, /* efo_supported_filters */
+ hunt_filter_reconfigure, /* efo_reconfigure */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ __checkReturn int
+efx_filter_insert(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec)
+{
+ efx_filter_ops_t *efop = enp->en_efop;
+
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+ return (efop->efo_add(enp, spec, B_FALSE));
+}
+
+ __checkReturn int
+efx_filter_remove(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec)
+{
+ efx_filter_ops_t *efop = enp->en_efop;
+
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+#if EFSYS_OPT_RX_SCALE
+ spec->efs_rss_context = enp->en_rss_context;
+#endif
+
+ return (efop->efo_delete(enp, spec));
+}
+
+ __checkReturn int
+efx_filter_restore(
+ __in efx_nic_t *enp)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+ if ((rc = enp->en_efop->efo_restore(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_filter_init(
+ __in efx_nic_t *enp)
+{
+ efx_filter_ops_t *efop;
+ int rc;
+
+ /* Check that efx_filter_spec_t is 64 bytes. */
+ EFX_STATIC_ASSERT(sizeof (efx_filter_spec_t) == 64);
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_FILTER));
+
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ efop = (efx_filter_ops_t *)&__efx_filter_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ efop = (efx_filter_ops_t *)&__efx_filter_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ efop = (efx_filter_ops_t *)&__efx_filter_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = efop->efo_init(enp)) != 0)
+ goto fail2;
+
+ enp->en_efop = efop;
+ enp->en_mod_flags |= EFX_MOD_FILTER;
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ enp->en_efop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_FILTER;
+ return (rc);
+}
+
+ void
+efx_filter_fini(
+ __in efx_nic_t *enp)
+{
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+ enp->en_efop->efo_fini(enp);
+
+ enp->en_efop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_FILTER;
+}
+
+ __checkReturn int
+efx_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+ EFSYS_ASSERT(enp->en_efop->efo_supported_filters != NULL);
+
+ if ((rc = enp->en_efop->efo_supported_filters(enp, list, length)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_filter_reconfigure(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *mac_addr,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+ if (enp->en_efop->efo_reconfigure != NULL) {
+ if ((rc = enp->en_efop->efo_reconfigure(enp, mac_addr,
+ all_unicst, mulcst,
+ all_mulcst, brdcst,
+ addrs, count)) != 0)
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_filter_spec_init_rx(
+ __inout efx_filter_spec_t *spec,
+ __in efx_filter_priority_t priority,
+ __in efx_filter_flag_t flags,
+ __in efx_rxq_t *erp)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3P(erp, !=, NULL);
+ EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
+ EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+
+ memset(spec, 0, sizeof (*spec));
+ spec->efs_priority = priority;
+ spec->efs_flags = EFX_FILTER_FLAG_RX | flags;
+ spec->efs_rss_context = EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT;
+ spec->efs_dmaq_id = (uint16_t)erp->er_index;
+}
+
+ void
+efx_filter_spec_init_tx(
+ __inout efx_filter_spec_t *spec,
+ __in efx_txq_t *etp)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3P(etp, !=, NULL);
+
+ memset(spec, 0, sizeof (*spec));
+ spec->efs_priority = EFX_FILTER_PRI_REQUIRED;
+ spec->efs_flags = EFX_FILTER_FLAG_TX;
+ spec->efs_dmaq_id = (uint16_t)etp->et_index;
+}
+
+
+/*
+ * Specify IPv4 host, transport protocol and port in a filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_ipv4_local(
+ __inout efx_filter_spec_t *spec,
+ __in uint8_t proto,
+ __in uint32_t host,
+ __in uint16_t port)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+
+ spec->efs_match_flags |=
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT;
+ spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
+ spec->efs_ip_proto = proto;
+ spec->efs_loc_host.eo_u32[0] = host;
+ spec->efs_loc_port = port;
+ return (0);
+}
+
+/*
+ * Specify IPv4 hosts, transport protocol and ports in a filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_ipv4_full(
+ __inout efx_filter_spec_t *spec,
+ __in uint8_t proto,
+ __in uint32_t lhost,
+ __in uint16_t lport,
+ __in uint32_t rhost,
+ __in uint16_t rport)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+
+ spec->efs_match_flags |=
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+ EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
+ spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
+ spec->efs_ip_proto = proto;
+ spec->efs_loc_host.eo_u32[0] = lhost;
+ spec->efs_loc_port = lport;
+ spec->efs_rem_host.eo_u32[0] = rhost;
+ spec->efs_rem_port = rport;
+ return (0);
+}
+
+/*
+ * Specify local Ethernet address and/or VID in filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_eth_local(
+ __inout efx_filter_spec_t *spec,
+ __in uint16_t vid,
+ __in const uint8_t *addr)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3P(addr, !=, NULL);
+
+ if (vid == EFX_FILTER_SPEC_VID_UNSPEC && addr == NULL)
+ return (EINVAL);
+
+ if (vid != EFX_FILTER_SPEC_VID_UNSPEC) {
+ spec->efs_match_flags |= EFX_FILTER_MATCH_OUTER_VID;
+ spec->efs_outer_vid = vid;
+ }
+ if (addr != NULL) {
+ spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC;
+ memcpy(spec->efs_loc_mac, addr, EFX_MAC_ADDR_LEN);
+ }
+ return (0);
+}
+
+/*
+ * Specify matching otherwise-unmatched unicast in a filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_uc_def(
+ __inout efx_filter_spec_t *spec)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+
+ spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+ return (0);
+}
+
+/*
+ * Specify matching otherwise-unmatched multicast in a filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_mc_def(
+ __inout efx_filter_spec_t *spec)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+
+ spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+ spec->efs_loc_mac[0] = 1;
+ return (0);
+}
+
+
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+/*
+ * "Fudge factors" - difference between programmed value and actual depth.
* Due to pipelined implementation we need to program H/W with a value that
* is larger than the hop limit we want.
*/
-#define FILTER_CTL_SRCH_FUDGE_WILD 3
-#define FILTER_CTL_SRCH_FUDGE_FULL 1
+#define FILTER_CTL_SRCH_FUDGE_WILD 3
+#define FILTER_CTL_SRCH_FUDGE_FULL 1
-/* Hard maximum hop limit. Hardware will time-out beyond 200-something.
+/*
+ * Hard maximum hop limit. Hardware will time-out beyond 200-something.
* We also need to avoid infinite loops in efx_filter_search() when the
* table is full.
*/
-#define FILTER_CTL_SRCH_MAX 200
+#define FILTER_CTL_SRCH_MAX 200
-/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
- * key derived from the n-tuple. */
+static __checkReturn int
+falconsiena_filter_spec_from_gen_spec(
+ __out falconsiena_filter_spec_t *fs_spec,
+ __in efx_filter_spec_t *gen_spec)
+{
+ int rc;
+ boolean_t is_full = B_FALSE;
+
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX)
+ EFSYS_ASSERT3U(gen_spec->efs_flags, ==, EFX_FILTER_FLAG_TX);
+ else
+ EFSYS_ASSERT3U(gen_spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+ /* Falconsiena only has one RSS context */
+ if ((gen_spec->efs_flags & EFX_FILTER_FLAG_RX_RSS) &&
+ gen_spec->efs_rss_context != 0) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ fs_spec->fsfs_flags = gen_spec->efs_flags;
+ fs_spec->fsfs_dmaq_id = gen_spec->efs_dmaq_id;
+
+ switch (gen_spec->efs_match_flags) {
+ case EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+ EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT:
+ is_full = B_TRUE;
+ /* Fall through */
+ case EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT: {
+ uint32_t rhost, host1, host2;
+ uint16_t rport, port1, port2;
+
+ if (gen_spec->efs_ether_type != EFX_ETHER_TYPE_IPV4) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+ if (gen_spec->efs_loc_port == 0 ||
+ (is_full && gen_spec->efs_rem_port == 0)) {
+ rc = EINVAL;
+ goto fail3;
+ }
+ switch (gen_spec->efs_ip_proto) {
+ case EFX_IPPROTO_TCP:
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_TX_TCP_FULL :
+ EFX_FS_FILTER_TX_TCP_WILD);
+ } else {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_RX_TCP_FULL :
+ EFX_FS_FILTER_RX_TCP_WILD);
+ }
+ break;
+ case EFX_IPPROTO_UDP:
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_TX_UDP_FULL :
+ EFX_FS_FILTER_TX_UDP_WILD);
+ } else {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_RX_UDP_FULL :
+ EFX_FS_FILTER_RX_UDP_WILD);
+ }
+ break;
+ default:
+ rc = ENOTSUP;
+ goto fail4;
+ }
+ /*
+ * The filter is constructed in terms of source and destination,
+ * with the odd wrinkle that the ports are swapped in a UDP
+ * wildcard filter. We need to convert from local and remote
+ * addresses (zero for a wildcard).
+ */
+ rhost = is_full ? gen_spec->efs_rem_host.eo_u32[0] : 0;
+ rport = is_full ? gen_spec->efs_rem_port : 0;
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ host1 = gen_spec->efs_loc_host.eo_u32[0];
+ host2 = rhost;
+ } else {
+ host1 = rhost;
+ host2 = gen_spec->efs_loc_host.eo_u32[0];
+ }
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ if (fs_spec->fsfs_type == EFX_FS_FILTER_TX_UDP_WILD) {
+ port1 = rport;
+ port2 = gen_spec->efs_loc_port;
+ } else {
+ port1 = gen_spec->efs_loc_port;
+ port2 = rport;
+ }
+ } else {
+ if (fs_spec->fsfs_type == EFX_FS_FILTER_RX_UDP_WILD) {
+ port1 = gen_spec->efs_loc_port;
+ port2 = rport;
+ } else {
+ port1 = rport;
+ port2 = gen_spec->efs_loc_port;
+ }
+ }
+ fs_spec->fsfs_dword[0] = (host1 << 16) | port1;
+ fs_spec->fsfs_dword[1] = (port2 << 16) | (host1 >> 16);
+ fs_spec->fsfs_dword[2] = host2;
+ break;
+ }
+
+ case EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_OUTER_VID:
+ is_full = B_TRUE;
+ /* Fall through */
+ case EFX_FILTER_MATCH_LOC_MAC:
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_TX_MAC_FULL :
+ EFX_FS_FILTER_TX_MAC_WILD);
+ } else {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_RX_MAC_FULL :
+ EFX_FS_FILTER_RX_MAC_WILD);
+ }
+ fs_spec->fsfs_dword[0] = is_full ? gen_spec->efs_outer_vid : 0;
+ fs_spec->fsfs_dword[1] =
+ gen_spec->efs_loc_mac[2] << 24 |
+ gen_spec->efs_loc_mac[3] << 16 |
+ gen_spec->efs_loc_mac[4] << 8 |
+ gen_spec->efs_loc_mac[5];
+ fs_spec->fsfs_dword[2] =
+ gen_spec->efs_loc_mac[0] << 8 |
+ gen_spec->efs_loc_mac[1];
+ break;
+
+ default:
+ EFSYS_ASSERT(B_FALSE);
+ rc = ENOTSUP;
+ goto fail5;
+ }
+
+ return (0);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
+ * key derived from the n-tuple.
+ */
static uint16_t
-efx_filter_tbl_hash(
- __in uint32_t key)
+falconsiena_filter_tbl_hash(
+ __in uint32_t key)
{
uint16_t tmp;
@@ -69,119 +619,119 @@ efx_filter_tbl_hash(
return (tmp);
}
-
-/* To allow for hash collisions, filter search continues at these
- * increments from the first possible entry selected by the hash. */
+/*
+ * To allow for hash collisions, filter search continues at these
+ * increments from the first possible entry selected by the hash.
+ */
static uint16_t
-efx_filter_tbl_increment(
+falconsiena_filter_tbl_increment(
__in uint32_t key)
{
return ((uint16_t)(key * 2 - 1));
}
static __checkReturn boolean_t
-efx_filter_test_used(
- __in efx_filter_tbl_t *eftp,
+falconsiena_filter_test_used(
+ __in falconsiena_filter_tbl_t *fsftp,
__in unsigned int index)
{
- EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL);
- return ((eftp->eft_bitmap[index / 32] & (1 << (index % 32))) != 0);
+ EFSYS_ASSERT3P(fsftp->fsft_bitmap, !=, NULL);
+ return ((fsftp->fsft_bitmap[index / 32] & (1 << (index % 32))) != 0);
}
static void
-efx_filter_set_used(
- __in efx_filter_tbl_t *eftp,
+falconsiena_filter_set_used(
+ __in falconsiena_filter_tbl_t *fsftp,
__in unsigned int index)
{
- EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL);
- eftp->eft_bitmap[index / 32] |= (1 << (index % 32));
- ++eftp->eft_used;
+ EFSYS_ASSERT3P(fsftp->fsft_bitmap, !=, NULL);
+ fsftp->fsft_bitmap[index / 32] |= (1 << (index % 32));
+ ++fsftp->fsft_used;
}
static void
-efx_filter_clear_used(
- __in efx_filter_tbl_t *eftp,
+falconsiena_filter_clear_used(
+ __in falconsiena_filter_tbl_t *fsftp,
__in unsigned int index)
{
- EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL);
- eftp->eft_bitmap[index / 32] &= ~(1 << (index % 32));
+ EFSYS_ASSERT3P(fsftp->fsft_bitmap, !=, NULL);
+ fsftp->fsft_bitmap[index / 32] &= ~(1 << (index % 32));
- --eftp->eft_used;
- EFSYS_ASSERT3U(eftp->eft_used, >=, 0);
+ --fsftp->fsft_used;
+ EFSYS_ASSERT3U(fsftp->fsft_used, >=, 0);
}
-static efx_filter_tbl_id_t
-efx_filter_tbl_id(
- __in efx_filter_type_t type)
+static falconsiena_filter_tbl_id_t
+falconsiena_filter_tbl_id(
+ __in falconsiena_filter_type_t type)
{
- efx_filter_tbl_id_t tbl_id;
-
- switch (type)
- {
- case EFX_FILTER_RX_TCP_FULL:
- case EFX_FILTER_RX_TCP_WILD:
- case EFX_FILTER_RX_UDP_FULL:
- case EFX_FILTER_RX_UDP_WILD:
- tbl_id = EFX_FILTER_TBL_RX_IP;
+ falconsiena_filter_tbl_id_t tbl_id;
+
+ switch (type) {
+ case EFX_FS_FILTER_RX_TCP_FULL:
+ case EFX_FS_FILTER_RX_TCP_WILD:
+ case EFX_FS_FILTER_RX_UDP_FULL:
+ case EFX_FS_FILTER_RX_UDP_WILD:
+ tbl_id = EFX_FS_FILTER_TBL_RX_IP;
break;
#if EFSYS_OPT_SIENA
- case EFX_FILTER_RX_MAC_FULL:
- case EFX_FILTER_RX_MAC_WILD:
- tbl_id = EFX_FILTER_TBL_RX_MAC;
+ case EFX_FS_FILTER_RX_MAC_FULL:
+ case EFX_FS_FILTER_RX_MAC_WILD:
+ tbl_id = EFX_FS_FILTER_TBL_RX_MAC;
break;
- case EFX_FILTER_TX_TCP_FULL:
- case EFX_FILTER_TX_TCP_WILD:
- case EFX_FILTER_TX_UDP_FULL:
- case EFX_FILTER_TX_UDP_WILD:
- tbl_id = EFX_FILTER_TBL_TX_IP;
+ case EFX_FS_FILTER_TX_TCP_FULL:
+ case EFX_FS_FILTER_TX_TCP_WILD:
+ case EFX_FS_FILTER_TX_UDP_FULL:
+ case EFX_FS_FILTER_TX_UDP_WILD:
+ tbl_id = EFX_FS_FILTER_TBL_TX_IP;
break;
- case EFX_FILTER_TX_MAC_FULL:
- case EFX_FILTER_TX_MAC_WILD:
- tbl_id = EFX_FILTER_TBL_RX_MAC;
+ case EFX_FS_FILTER_TX_MAC_FULL:
+ case EFX_FS_FILTER_TX_MAC_WILD:
+ tbl_id = EFX_FS_FILTER_TBL_TX_MAC;
break;
#endif /* EFSYS_OPT_SIENA */
default:
EFSYS_ASSERT(B_FALSE);
+ tbl_id = EFX_FS_FILTER_NTBLS;
break;
}
return (tbl_id);
}
static void
-efx_filter_reset_search_depth(
- __inout efx_filter_t *efp,
- __in efx_filter_tbl_id_t tbl_id)
+falconsiena_filter_reset_search_depth(
+ __inout falconsiena_filter_t *fsfp,
+ __in falconsiena_filter_tbl_id_t tbl_id)
{
- switch (tbl_id)
- {
- case EFX_FILTER_TBL_RX_IP:
- efp->ef_depth[EFX_FILTER_RX_TCP_FULL] = 0;
- efp->ef_depth[EFX_FILTER_RX_TCP_WILD] = 0;
- efp->ef_depth[EFX_FILTER_RX_UDP_FULL] = 0;
- efp->ef_depth[EFX_FILTER_RX_UDP_WILD] = 0;
+ switch (tbl_id) {
+ case EFX_FS_FILTER_TBL_RX_IP:
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_TCP_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_TCP_WILD] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_UDP_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_UDP_WILD] = 0;
break;
#if EFSYS_OPT_SIENA
- case EFX_FILTER_TBL_RX_MAC:
- efp->ef_depth[EFX_FILTER_RX_MAC_FULL] = 0;
- efp->ef_depth[EFX_FILTER_RX_MAC_WILD] = 0;
+ case EFX_FS_FILTER_TBL_RX_MAC:
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_MAC_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_MAC_WILD] = 0;
break;
- case EFX_FILTER_TBL_TX_IP:
- efp->ef_depth[EFX_FILTER_TX_TCP_FULL] = 0;
- efp->ef_depth[EFX_FILTER_TX_TCP_WILD] = 0;
- efp->ef_depth[EFX_FILTER_TX_UDP_FULL] = 0;
- efp->ef_depth[EFX_FILTER_TX_UDP_WILD] = 0;
+ case EFX_FS_FILTER_TBL_TX_IP:
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_TCP_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_TCP_WILD] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_UDP_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_UDP_WILD] = 0;
break;
- case EFX_FILTER_TBL_TX_MAC:
- efp->ef_depth[EFX_FILTER_TX_MAC_FULL] = 0;
- efp->ef_depth[EFX_FILTER_TX_MAC_WILD] = 0;
+ case EFX_FS_FILTER_TBL_TX_MAC:
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_MAC_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_MAC_WILD] = 0;
break;
#endif /* EFSYS_OPT_SIENA */
@@ -192,36 +742,36 @@ efx_filter_reset_search_depth(
}
static void
-efx_filter_push_rx_limits(
+falconsiena_filter_push_rx_limits(
__in efx_nic_t *enp)
{
- efx_filter_t *efp = &enp->en_filter;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
efx_oword_t oword;
EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_TCP_FULL_SRCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_TCP_FULL] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_TCP_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_TCP_WILD_SRCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_TCP_WILD] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_TCP_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_UDP_FULL_SRCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_UDP_FULL] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_UDP_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_UDP_WILD_SRCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_UDP_WILD] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_UDP_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
#if EFSYS_OPT_SIENA
- if (efp->ef_tbl[EFX_FILTER_TBL_RX_MAC].eft_size) {
+ if (fsfp->fsf_tbl[EFX_FS_FILTER_TBL_RX_MAC].fsft_size) {
EFX_SET_OWORD_FIELD(oword,
FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_MAC_FULL] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_MAC_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(oword,
FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_MAC_WILD] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_MAC_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
}
#endif /* EFSYS_OPT_SIENA */
@@ -230,150 +780,177 @@ efx_filter_push_rx_limits(
}
static void
-efx_filter_push_tx_limits(
+falconsiena_filter_push_tx_limits(
__in efx_nic_t *enp)
{
- efx_filter_t *efp = &enp->en_filter;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
efx_oword_t oword;
- if (efp->ef_tbl[EFX_FILTER_TBL_TX_IP].eft_size == 0)
- return;
-
EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);
- EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE,
- efp->ef_depth[EFX_FILTER_TX_TCP_FULL] +
- FILTER_CTL_SRCH_FUDGE_FULL);
- EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE,
- efp->ef_depth[EFX_FILTER_TX_TCP_WILD] +
- FILTER_CTL_SRCH_FUDGE_WILD);
- EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE,
- efp->ef_depth[EFX_FILTER_TX_UDP_FULL] +
- FILTER_CTL_SRCH_FUDGE_FULL);
- EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE,
- efp->ef_depth[EFX_FILTER_TX_UDP_WILD] +
- FILTER_CTL_SRCH_FUDGE_WILD);
+ if (fsfp->fsf_tbl[EFX_FS_FILTER_TBL_TX_IP].fsft_size != 0) {
+ EFX_SET_OWORD_FIELD(oword,
+ FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_TCP_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(oword,
+ FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_TCP_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+ EFX_SET_OWORD_FIELD(oword,
+ FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_UDP_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(oword,
+ FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_UDP_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+ }
+
+ if (fsfp->fsf_tbl[EFX_FS_FILTER_TBL_TX_MAC].fsft_size != 0) {
+ EFX_SET_OWORD_FIELD(
+ oword, FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_MAC_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(
+ oword, FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_MAC_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+ }
EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
}
/* Build a filter entry and return its n-tuple key. */
static __checkReturn uint32_t
-efx_filter_build(
+falconsiena_filter_build(
__out efx_oword_t *filter,
- __in efx_filter_spec_t *spec)
+ __in falconsiena_filter_spec_t *spec)
{
uint32_t dword3;
uint32_t key;
- uint8_t type = spec->efs_type;
- uint8_t flags = spec->efs_flags;
+ uint8_t type = spec->fsfs_type;
+ uint32_t flags = spec->fsfs_flags;
- switch (efx_filter_tbl_id(type)) {
- case EFX_FILTER_TBL_RX_IP: {
- boolean_t is_udp = (type == EFX_FILTER_RX_UDP_FULL ||
- type == EFX_FILTER_RX_UDP_WILD);
+ switch (falconsiena_filter_tbl_id(type)) {
+ case EFX_FS_FILTER_TBL_RX_IP: {
+ boolean_t is_udp = (type == EFX_FS_FILTER_RX_UDP_FULL ||
+ type == EFX_FS_FILTER_RX_UDP_WILD);
EFX_POPULATE_OWORD_7(*filter,
- FRF_BZ_RSS_EN, (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,
- FRF_BZ_SCATTER_EN, (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,
+ FRF_BZ_RSS_EN,
+ (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,
+ FRF_BZ_SCATTER_EN,
+ (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,
FRF_AZ_TCP_UDP, is_udp,
- FRF_AZ_RXQ_ID, spec->efs_dmaq_id,
- EFX_DWORD_2, spec->efs_dword[2],
- EFX_DWORD_1, spec->efs_dword[1],
- EFX_DWORD_0, spec->efs_dword[0]);
+ FRF_AZ_RXQ_ID, spec->fsfs_dmaq_id,
+ EFX_DWORD_2, spec->fsfs_dword[2],
+ EFX_DWORD_1, spec->fsfs_dword[1],
+ EFX_DWORD_0, spec->fsfs_dword[0]);
dword3 = is_udp;
break;
}
#if EFSYS_OPT_SIENA
- case EFX_FILTER_TBL_RX_MAC: {
- boolean_t is_wild = (type == EFX_FILTER_RX_MAC_WILD);
- EFX_POPULATE_OWORD_8(*filter,
- FRF_CZ_RMFT_RSS_EN, (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,
- FRF_CZ_RMFT_SCATTER_EN, (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,
- FRF_CZ_RMFT_IP_OVERRIDE, (flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) ? 1 : 0,
- FRF_CZ_RMFT_RXQ_ID, spec->efs_dmaq_id,
+ case EFX_FS_FILTER_TBL_RX_MAC: {
+ boolean_t is_wild = (type == EFX_FS_FILTER_RX_MAC_WILD);
+ EFX_POPULATE_OWORD_7(*filter,
+ FRF_CZ_RMFT_RSS_EN,
+ (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,
+ FRF_CZ_RMFT_SCATTER_EN,
+ (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,
+ FRF_CZ_RMFT_RXQ_ID, spec->fsfs_dmaq_id,
FRF_CZ_RMFT_WILDCARD_MATCH, is_wild,
- FRF_CZ_RMFT_DEST_MAC_DW1, spec->efs_dword[2],
- FRF_CZ_RMFT_DEST_MAC_DW0, spec->efs_dword[1],
- FRF_CZ_RMFT_VLAN_ID, spec->efs_dword[0]);
+ FRF_CZ_RMFT_DEST_MAC_DW1, spec->fsfs_dword[2],
+ FRF_CZ_RMFT_DEST_MAC_DW0, spec->fsfs_dword[1],
+ FRF_CZ_RMFT_VLAN_ID, spec->fsfs_dword[0]);
dword3 = is_wild;
break;
}
#endif /* EFSYS_OPT_SIENA */
- case EFX_FILTER_TBL_TX_IP: {
- boolean_t is_udp = (type == EFX_FILTER_TX_UDP_FULL ||
- type == EFX_FILTER_TX_UDP_WILD);
+ case EFX_FS_FILTER_TBL_TX_IP: {
+ boolean_t is_udp = (type == EFX_FS_FILTER_TX_UDP_FULL ||
+ type == EFX_FS_FILTER_TX_UDP_WILD);
EFX_POPULATE_OWORD_5(*filter,
FRF_CZ_TIFT_TCP_UDP, is_udp,
- FRF_CZ_TIFT_TXQ_ID, spec->efs_dmaq_id,
- EFX_DWORD_2, spec->efs_dword[2],
- EFX_DWORD_1, spec->efs_dword[1],
- EFX_DWORD_0, spec->efs_dword[0]);
- dword3 = is_udp | spec->efs_dmaq_id << 1;
+ FRF_CZ_TIFT_TXQ_ID, spec->fsfs_dmaq_id,
+ EFX_DWORD_2, spec->fsfs_dword[2],
+ EFX_DWORD_1, spec->fsfs_dword[1],
+ EFX_DWORD_0, spec->fsfs_dword[0]);
+ dword3 = is_udp | spec->fsfs_dmaq_id << 1;
break;
}
#if EFSYS_OPT_SIENA
- case EFX_FILTER_TBL_TX_MAC: {
- boolean_t is_wild = (type == EFX_FILTER_TX_MAC_WILD);
+ case EFX_FS_FILTER_TBL_TX_MAC: {
+ boolean_t is_wild = (type == EFX_FS_FILTER_TX_MAC_WILD);
EFX_POPULATE_OWORD_5(*filter,
- FRF_CZ_TMFT_TXQ_ID, spec->efs_dmaq_id,
+ FRF_CZ_TMFT_TXQ_ID, spec->fsfs_dmaq_id,
FRF_CZ_TMFT_WILDCARD_MATCH, is_wild,
- FRF_CZ_TMFT_SRC_MAC_DW1, spec->efs_dword[2],
- FRF_CZ_TMFT_SRC_MAC_DW0, spec->efs_dword[1],
- FRF_CZ_TMFT_VLAN_ID, spec->efs_dword[0]);
- dword3 = is_wild | spec->efs_dmaq_id << 1;
+ FRF_CZ_TMFT_SRC_MAC_DW1, spec->fsfs_dword[2],
+ FRF_CZ_TMFT_SRC_MAC_DW0, spec->fsfs_dword[1],
+ FRF_CZ_TMFT_VLAN_ID, spec->fsfs_dword[0]);
+ dword3 = is_wild | spec->fsfs_dmaq_id << 1;
break;
}
#endif /* EFSYS_OPT_SIENA */
default:
EFSYS_ASSERT(B_FALSE);
+ return (0);
}
- key = spec->efs_dword[0] ^ spec->efs_dword[1] ^ spec->efs_dword[2] ^ dword3;
+ key =
+ spec->fsfs_dword[0] ^
+ spec->fsfs_dword[1] ^
+ spec->fsfs_dword[2] ^
+ dword3;
+
return (key);
}
static __checkReturn int
-efx_filter_push_entry(
+falconsiena_filter_push_entry(
__inout efx_nic_t *enp,
- __in efx_filter_type_t type,
+ __in falconsiena_filter_type_t type,
__in int index,
__in efx_oword_t *eop)
{
int rc;
- switch (type)
- {
- case EFX_FILTER_RX_TCP_FULL:
- case EFX_FILTER_RX_TCP_WILD:
- case EFX_FILTER_RX_UDP_FULL:
- case EFX_FILTER_RX_UDP_WILD:
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_FILTER_TBL0, index, eop);
+ switch (type) {
+ case EFX_FS_FILTER_RX_TCP_FULL:
+ case EFX_FS_FILTER_RX_TCP_WILD:
+ case EFX_FS_FILTER_RX_UDP_FULL:
+ case EFX_FS_FILTER_RX_UDP_WILD:
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_FILTER_TBL0, index,
+ eop, B_TRUE);
break;
#if EFSYS_OPT_SIENA
- case EFX_FILTER_RX_MAC_FULL:
- case EFX_FILTER_RX_MAC_WILD:
- EFX_BAR_TBL_WRITEO(enp, FR_CZ_RX_MAC_FILTER_TBL0, index, eop);
+ case EFX_FS_FILTER_RX_MAC_FULL:
+ case EFX_FS_FILTER_RX_MAC_WILD:
+ EFX_BAR_TBL_WRITEO(enp, FR_CZ_RX_MAC_FILTER_TBL0, index,
+ eop, B_TRUE);
break;
- case EFX_FILTER_TX_TCP_FULL:
- case EFX_FILTER_TX_TCP_WILD:
- case EFX_FILTER_TX_UDP_FULL:
- case EFX_FILTER_TX_UDP_WILD:
- EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_FILTER_TBL0, index, eop);
+ case EFX_FS_FILTER_TX_TCP_FULL:
+ case EFX_FS_FILTER_TX_TCP_WILD:
+ case EFX_FS_FILTER_TX_UDP_FULL:
+ case EFX_FS_FILTER_TX_UDP_WILD:
+ EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_FILTER_TBL0, index,
+ eop, B_TRUE);
break;
- case EFX_FILTER_TX_MAC_FULL:
- case EFX_FILTER_TX_MAC_WILD:
- EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_MAC_FILTER_TBL0, index, eop);
+ case EFX_FS_FILTER_TX_MAC_FULL:
+ case EFX_FS_FILTER_TX_MAC_WILD:
+ EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_MAC_FILTER_TBL0, index,
+ eop, B_TRUE);
break;
#endif /* EFSYS_OPT_SIENA */
default:
+ EFSYS_ASSERT(B_FALSE);
rc = ENOTSUP;
goto fail1;
}
@@ -385,30 +962,34 @@ fail1:
static __checkReturn boolean_t
-efx_filter_equal(
- __in const efx_filter_spec_t *left,
- __in const efx_filter_spec_t *right)
+falconsiena_filter_equal(
+ __in const falconsiena_filter_spec_t *left,
+ __in const falconsiena_filter_spec_t *right)
{
- efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(left->efs_type);
+ falconsiena_filter_tbl_id_t tbl_id;
- if (left->efs_type != right->efs_type)
+ tbl_id = falconsiena_filter_tbl_id(left->fsfs_type);
+
+
+ if (left->fsfs_type != right->fsfs_type)
return (B_FALSE);
- if (memcmp(left->efs_dword, right->efs_dword, sizeof(left->efs_dword)))
+ if (memcmp(left->fsfs_dword, right->fsfs_dword,
+ sizeof (left->fsfs_dword)))
return (B_FALSE);
- if ((tbl_id == EFX_FILTER_TBL_TX_IP ||
- tbl_id == EFX_FILTER_TBL_TX_MAC) &&
- left->efs_dmaq_id != right->efs_dmaq_id)
+ if ((tbl_id == EFX_FS_FILTER_TBL_TX_IP ||
+ tbl_id == EFX_FS_FILTER_TBL_TX_MAC) &&
+ left->fsfs_dmaq_id != right->fsfs_dmaq_id)
return (B_FALSE);
return (B_TRUE);
}
static __checkReturn int
-efx_filter_search(
- __in efx_filter_tbl_t *eftp,
- __in efx_filter_spec_t *spec,
+falconsiena_filter_search(
+ __in falconsiena_filter_tbl_t *fsftp,
+ __in falconsiena_filter_spec_t *spec,
__in uint32_t key,
__in boolean_t for_insert,
__out int *filter_index,
@@ -416,18 +997,20 @@ efx_filter_search(
{
unsigned hash, incr, filter_idx, depth;
- hash = efx_filter_tbl_hash(key);
- incr = efx_filter_tbl_increment(key);
+ hash = falconsiena_filter_tbl_hash(key);
+ incr = falconsiena_filter_tbl_increment(key);
- filter_idx = hash & (eftp->eft_size - 1);
+ filter_idx = hash & (fsftp->fsft_size - 1);
depth = 1;
for (;;) {
- /* Return success if entry is used and matches this spec
+ /*
+ * Return success if entry is used and matches this spec
* or entry is unused and we are trying to insert.
*/
- if (efx_filter_test_used(eftp, filter_idx) ?
- efx_filter_equal(spec, &eftp->eft_spec[filter_idx]) :
+ if (falconsiena_filter_test_used(fsftp, filter_idx) ?
+ falconsiena_filter_equal(spec,
+ &fsftp->fsft_spec[filter_idx]) :
for_insert) {
*filter_index = filter_idx;
*depth_required = depth;
@@ -436,594 +1019,421 @@ efx_filter_search(
/* Return failure if we reached the maximum search depth */
if (depth == FILTER_CTL_SRCH_MAX)
- return for_insert ? EBUSY : ENOENT;
+ return (for_insert ? EBUSY : ENOENT);
- filter_idx = (filter_idx + incr) & (eftp->eft_size - 1);
+ filter_idx = (filter_idx + incr) & (fsftp->fsft_size - 1);
++depth;
}
}
- __checkReturn int
-efx_filter_insert_filter(
- __in efx_nic_t *enp,
- __in efx_filter_spec_t *spec,
- __in boolean_t replace)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(spec->efs_type);
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
- efx_filter_spec_t *saved_spec;
- efx_oword_t filter;
- int filter_idx;
- unsigned int depth;
- int state;
- uint32_t key;
- int rc;
-
- if (eftp->eft_size == 0)
- return (EINVAL);
-
- key = efx_filter_build(&filter, spec);
-
- EFSYS_LOCK(enp->en_eslp, state);
-
- rc = efx_filter_search(eftp, spec, key, B_TRUE, &filter_idx, &depth);
- if (rc != 0)
- goto done;
-
- EFSYS_ASSERT3U(filter_idx, <, eftp->eft_size);
- saved_spec = &eftp->eft_spec[filter_idx];
-
- if (efx_filter_test_used(eftp, filter_idx)) {
- if (replace == B_FALSE) {
- rc = EEXIST;
- goto done;
- }
- }
- efx_filter_set_used(eftp, filter_idx);
- *saved_spec = *spec;
-
- if (efp->ef_depth[spec->efs_type] < depth) {
- efp->ef_depth[spec->efs_type] = depth;
- if (tbl_id == EFX_FILTER_TBL_TX_IP ||
- tbl_id == EFX_FILTER_TBL_TX_MAC)
- efx_filter_push_tx_limits(enp);
- else
- efx_filter_push_rx_limits(enp);
- }
-
- efx_filter_push_entry(enp, spec->efs_type, filter_idx, &filter);
-
-done:
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (rc);
-}
-
static void
-efx_filter_clear_entry(
+falconsiena_filter_clear_entry(
__in efx_nic_t *enp,
- __in efx_filter_tbl_t *eftp,
+ __in falconsiena_filter_tbl_t *fsftp,
__in int index)
{
efx_oword_t filter;
- if (efx_filter_test_used(eftp, index)) {
- efx_filter_clear_used(eftp, index);
+ if (falconsiena_filter_test_used(fsftp, index)) {
+ falconsiena_filter_clear_used(fsftp, index);
EFX_ZERO_OWORD(filter);
- efx_filter_push_entry(enp, eftp->eft_spec[index].efs_type,
+ falconsiena_filter_push_entry(enp,
+ fsftp->fsft_spec[index].fsfs_type,
index, &filter);
- memset(&eftp->eft_spec[index], 0, sizeof(eftp->eft_spec[0]));
+ memset(&fsftp->fsft_spec[index],
+ 0, sizeof (fsftp->fsft_spec[0]));
}
}
- __checkReturn int
-efx_filter_remove_filter(
- __in efx_nic_t *enp,
- __in efx_filter_spec_t *spec)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(spec->efs_type);
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
- efx_filter_spec_t *saved_spec;
- efx_oword_t filter;
- int filter_idx;
- unsigned int depth;
- int state;
- uint32_t key;
- int rc;
-
- key = efx_filter_build(&filter, spec);
-
- EFSYS_LOCK(enp->en_eslp, state);
-
- rc = efx_filter_search(eftp, spec, key, B_FALSE, &filter_idx, &depth);
- if (rc != 0)
- goto out;
-
- saved_spec = &eftp->eft_spec[filter_idx];
-
- efx_filter_clear_entry(enp, eftp, filter_idx);
- if (eftp->eft_used == 0)
- efx_filter_reset_search_depth(efp, tbl_id);
-
- rc = 0;
-
-out:
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (rc);
-}
-
- void
-efx_filter_remove_index(
- __inout efx_nic_t *enp,
- __in efx_filter_type_t type,
- __in int index)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(type);
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
- int state;
-
- if (index < 0)
- return;
-
- EFSYS_LOCK(enp->en_eslp, state);
-
- efx_filter_clear_entry(enp, eftp, index);
- if (eftp->eft_used == 0)
- efx_filter_reset_search_depth(efp, tbl_id);
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-}
-
void
-efx_filter_tbl_clear(
- __inout efx_nic_t *enp,
- __in efx_filter_tbl_id_t tbl_id)
+falconsiena_filter_tbl_clear(
+ __in efx_nic_t *enp,
+ __in falconsiena_filter_tbl_id_t tbl_id)
{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_t *fsftp = &fsfp->fsf_tbl[tbl_id];
int index;
int state;
EFSYS_LOCK(enp->en_eslp, state);
- for (index = 0; index < eftp->eft_size; ++index) {
- efx_filter_clear_entry(enp, eftp, index);
+ for (index = 0; index < fsftp->fsft_size; ++index) {
+ falconsiena_filter_clear_entry(enp, fsftp, index);
}
- if (eftp->eft_used == 0)
- efx_filter_reset_search_depth(efp, tbl_id);
+ if (fsftp->fsft_used == 0)
+ falconsiena_filter_reset_search_depth(fsfp, tbl_id);
EFSYS_UNLOCK(enp->en_eslp, state);
}
-/* Restore filter state after a reset */
- void
-efx_filter_restore(
+static __checkReturn int
+falconsiena_filter_init(
__in efx_nic_t *enp)
{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id;
- efx_filter_tbl_t *eftp;
- efx_filter_spec_t *spec;
- efx_oword_t filter;
- int filter_idx;
- int state;
-
- EFSYS_LOCK(enp->en_eslp, state);
+ falconsiena_filter_t *fsfp;
+ falconsiena_filter_tbl_t *fsftp;
+ int tbl_id;
+ int rc;
- for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) {
- eftp = &efp->ef_tbl[tbl_id];
- for (filter_idx = 0; filter_idx < eftp->eft_size; filter_idx++) {
- if (!efx_filter_test_used(eftp, filter_idx))
- continue;
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (falconsiena_filter_t), fsfp);
- spec = &eftp->eft_spec[filter_idx];
- efx_filter_build(&filter, spec);
- efx_filter_push_entry(enp, spec->efs_type,
- filter_idx, &filter);
- }
+ if (!fsfp) {
+ rc = ENOMEM;
+ goto fail1;
}
- efx_filter_push_rx_limits(enp);
- efx_filter_push_tx_limits(enp);
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-}
-
- void
-efx_filter_redirect_index(
- __inout efx_nic_t *enp,
- __in efx_filter_type_t type,
- __in int filter_index,
- __in int rxq_index)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_t *eftp =
- &efp->ef_tbl[efx_filter_tbl_id(type)];
- efx_filter_spec_t *spec;
- efx_oword_t filter;
- int state;
-
- EFSYS_LOCK(enp->en_eslp, state);
+ enp->en_filter.ef_falconsiena_filter = fsfp;
- spec = &eftp->eft_spec[filter_index];
- spec->efs_dmaq_id = (uint16_t)rxq_index;
-
- efx_filter_build(&filter, spec);
- efx_filter_push_entry(enp, spec->efs_type, filter_index, &filter);
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-}
-
- __checkReturn int
-efx_filter_init(
- __in efx_nic_t *enp)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_t *eftp;
- int tbl_id;
- int rc;
-
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
- EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_FILTER));
-
- switch (enp->en_family)
- {
+ switch (enp->en_family) {
#if EFSYS_OPT_FALCON
case EFX_FAMILY_FALCON:
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_IP];
- eftp->eft_size = FR_AZ_RX_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_RX_IP];
+ fsftp->fsft_size = FR_AZ_RX_FILTER_TBL0_ROWS;
break;
#endif /* EFSYS_OPT_FALCON */
#if EFSYS_OPT_SIENA
case EFX_FAMILY_SIENA:
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_IP];
- eftp->eft_size = FR_AZ_RX_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_RX_IP];
+ fsftp->fsft_size = FR_AZ_RX_FILTER_TBL0_ROWS;
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_MAC];
- eftp->eft_size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_RX_MAC];
+ fsftp->fsft_size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_TX_IP];
- eftp->eft_size = FR_CZ_TX_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_TX_IP];
+ fsftp->fsft_size = FR_CZ_TX_FILTER_TBL0_ROWS;
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_TX_MAC];
- eftp->eft_size = FR_CZ_TX_MAC_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_TX_MAC];
+ fsftp->fsft_size = FR_CZ_TX_MAC_FILTER_TBL0_ROWS;
break;
#endif /* EFSYS_OPT_SIENA */
default:
rc = ENOTSUP;
- goto fail1;
+ goto fail2;
}
- for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) {
+ for (tbl_id = 0; tbl_id < EFX_FS_FILTER_NTBLS; tbl_id++) {
unsigned int bitmap_size;
- eftp = &efp->ef_tbl[tbl_id];
- if (eftp->eft_size == 0)
+ fsftp = &fsfp->fsf_tbl[tbl_id];
+ if (fsftp->fsft_size == 0)
continue;
- EFX_STATIC_ASSERT(sizeof(eftp->eft_bitmap[0]) == sizeof(uint32_t));
- bitmap_size = (eftp->eft_size + (sizeof(uint32_t) * 8) - 1) / 8;
+ EFX_STATIC_ASSERT(sizeof (fsftp->fsft_bitmap[0]) ==
+ sizeof (uint32_t));
+ bitmap_size =
+ (fsftp->fsft_size + (sizeof (uint32_t) * 8) - 1) / 8;
- EFSYS_KMEM_ALLOC(enp->en_esip, bitmap_size, eftp->eft_bitmap);
- if (!eftp->eft_bitmap) {
+ EFSYS_KMEM_ALLOC(enp->en_esip, bitmap_size, fsftp->fsft_bitmap);
+ if (!fsftp->fsft_bitmap) {
rc = ENOMEM;
- goto fail2;
+ goto fail3;
}
- EFSYS_KMEM_ALLOC(enp->en_esip, eftp->eft_size * sizeof(*eftp->eft_spec),
- eftp->eft_spec);
- if (!eftp->eft_spec) {
+ EFSYS_KMEM_ALLOC(enp->en_esip,
+ fsftp->fsft_size * sizeof (*fsftp->fsft_spec),
+ fsftp->fsft_spec);
+ if (!fsftp->fsft_spec) {
rc = ENOMEM;
- goto fail3;
+ goto fail4;
}
- memset(eftp->eft_spec, 0, eftp->eft_size * sizeof(*eftp->eft_spec));
+ memset(fsftp->fsft_spec, 0,
+ fsftp->fsft_size * sizeof (*fsftp->fsft_spec));
}
- enp->en_mod_flags |= EFX_MOD_FILTER;
return (0);
+fail4:
+ EFSYS_PROBE(fail4);
+
fail3:
EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
- efx_filter_fini(enp);
+ falconsiena_filter_fini(enp);
fail1:
EFSYS_PROBE1(fail1, int, rc);
return (rc);
}
- void
-efx_filter_fini(
+static void
+falconsiena_filter_fini(
__in efx_nic_t *enp)
{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_id_t tbl_id;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
- for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) {
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
+ if (fsfp == NULL)
+ return;
+
+ for (tbl_id = 0; tbl_id < EFX_FS_FILTER_NTBLS; tbl_id++) {
+ falconsiena_filter_tbl_t *fsftp = &fsfp->fsf_tbl[tbl_id];
unsigned int bitmap_size;
- EFX_STATIC_ASSERT(sizeof(eftp->eft_bitmap[0]) == sizeof(uint32_t));
- bitmap_size = (eftp->eft_size + (sizeof(uint32_t) * 8) - 1) / 8;
+ EFX_STATIC_ASSERT(sizeof (fsftp->fsft_bitmap[0]) ==
+ sizeof (uint32_t));
+ bitmap_size =
+ (fsftp->fsft_size + (sizeof (uint32_t) * 8) - 1) / 8;
- if (eftp->eft_bitmap != NULL) {
+ if (fsftp->fsft_bitmap != NULL) {
EFSYS_KMEM_FREE(enp->en_esip, bitmap_size,
- eftp->eft_bitmap);
- eftp->eft_bitmap = NULL;
+ fsftp->fsft_bitmap);
+ fsftp->fsft_bitmap = NULL;
}
- if (eftp->eft_spec != NULL) {
- EFSYS_KMEM_FREE(enp->en_esip, eftp->eft_size *
- sizeof(*eftp->eft_spec), eftp->eft_spec);
- eftp->eft_spec = NULL;
+ if (fsftp->fsft_spec != NULL) {
+ EFSYS_KMEM_FREE(enp->en_esip, fsftp->fsft_size *
+ sizeof (*fsftp->fsft_spec), fsftp->fsft_spec);
+ fsftp->fsft_spec = NULL;
}
}
- enp->en_mod_flags &= ~EFX_MOD_FILTER;
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (falconsiena_filter_t),
+ enp->en_filter.ef_falconsiena_filter);
}
-extern void
-efx_filter_spec_rx_ipv4_tcp_full(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t src_ip,
- __in uint16_t src_tcp,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp)
+/* Restore filter state after a reset */
+static __checkReturn int
+falconsiena_filter_restore(
+ __in efx_nic_t *enp)
{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_id_t tbl_id;
+ falconsiena_filter_tbl_t *fsftp;
+ falconsiena_filter_spec_t *spec;
+ efx_oword_t filter;
+ int filter_idx;
+ int state;
+ int rc;
- spec->efs_type = EFX_FILTER_RX_TCP_FULL;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = src_tcp | src_ip << 16;
- spec->efs_dword[1] = dest_tcp << 16 | src_ip >> 16;
- spec->efs_dword[2] = dest_ip;
-}
+ EFSYS_LOCK(enp->en_eslp, state);
-extern void
-efx_filter_spec_rx_ipv4_tcp_wild(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+ for (tbl_id = 0; tbl_id < EFX_FS_FILTER_NTBLS; tbl_id++) {
+ fsftp = &fsfp->fsf_tbl[tbl_id];
+ for (filter_idx = 0;
+ filter_idx < fsftp->fsft_size;
+ filter_idx++) {
+ if (!falconsiena_filter_test_used(fsftp, filter_idx))
+ continue;
- spec->efs_type = EFX_FILTER_RX_TCP_WILD;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = 0;
- spec->efs_dword[1] = dest_tcp << 16;
- spec->efs_dword[2] = dest_ip;
-}
+ spec = &fsftp->fsft_spec[filter_idx];
+ if ((rc = falconsiena_filter_build(&filter, spec)) != 0)
+ goto fail1;
+ if ((rc = falconsiena_filter_push_entry(enp,
+ spec->fsfs_type, filter_idx, &filter)) != 0)
+ goto fail2;
+ }
+ }
-extern void
-efx_filter_spec_rx_ipv4_udp_full(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t src_ip,
- __in uint16_t src_udp,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+ falconsiena_filter_push_rx_limits(enp);
+ falconsiena_filter_push_tx_limits(enp);
- spec->efs_type = EFX_FILTER_RX_UDP_FULL;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = src_udp | src_ip << 16;
- spec->efs_dword[1] = dest_udp << 16 | src_ip >> 16;
- spec->efs_dword[2] = dest_ip;
-}
+ EFSYS_UNLOCK(enp->en_eslp, state);
-extern void
-efx_filter_spec_rx_ipv4_udp_wild(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+ return (0);
- spec->efs_type = EFX_FILTER_RX_UDP_WILD;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = dest_udp;
- spec->efs_dword[1] = 0;
- spec->efs_dword[2] = dest_ip;
-}
+fail2:
+ EFSYS_PROBE(fail2);
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_rx_mac_full(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint16_t vlan_id,
- __in uint8_t *dest_mac)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(dest_mac, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER |
- EFX_FILTER_FLAG_RX_OVERRIDE_IP)) == 0);
-
- spec->efs_type = EFX_FILTER_RX_MAC_FULL;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = vlan_id;
- spec->efs_dword[1] =
- dest_mac[2] << 24 |
- dest_mac[3] << 16 |
- dest_mac[4] << 8 |
- dest_mac[5];
- spec->efs_dword[2] =
- dest_mac[0] << 8 |
- dest_mac[1];
-}
-#endif /* EFSYS_OPT_SIENA */
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_rx_mac_wild(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint8_t *dest_mac)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(dest_mac, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER |
- EFX_FILTER_FLAG_RX_OVERRIDE_IP)) == 0);
-
- spec->efs_type = EFX_FILTER_RX_MAC_WILD;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = 0;
- spec->efs_dword[1] =
- dest_mac[2] << 24 |
- dest_mac[3] << 16 |
- dest_mac[4] << 8 |
- dest_mac[5];
- spec->efs_dword[2] =
- dest_mac[0] << 8 |
- dest_mac[1];
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ return (rc);
}
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_ipv4_tcp_full(
+static __checkReturn int
+falconsiena_filter_add(
+ __in efx_nic_t *enp,
__inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_tcp,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp)
+ __in boolean_t may_replace)
{
- EFSYS_ASSERT3P(spec, !=, NULL);
+ int rc;
+ falconsiena_filter_spec_t fs_spec;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_id_t tbl_id;
+ falconsiena_filter_tbl_t *fsftp;
+ falconsiena_filter_spec_t *saved_fs_spec;
+ efx_oword_t filter;
+ int filter_idx;
+ unsigned int depth;
+ int state;
+ uint32_t key;
- spec->efs_type = EFX_FILTER_TX_TCP_FULL;
- spec->efs_flags = 0;
- spec->efs_dword[0] = src_tcp | src_ip << 16;
- spec->efs_dword[1] = dest_tcp << 16 | src_ip >> 16;
- spec->efs_dword[2] = dest_ip;
-}
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_ipv4_tcp_wild(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_tcp)
-{
EFSYS_ASSERT3P(spec, !=, NULL);
- spec->efs_type = EFX_FILTER_TX_TCP_WILD;
- spec->efs_flags = 0;
- spec->efs_dword[0] = 0;
- spec->efs_dword[1] = src_tcp << 16;
- spec->efs_dword[2] = src_ip;
-}
-#endif /* EFSYS_OPT_SIENA */
+ if ((rc = falconsiena_filter_spec_from_gen_spec(&fs_spec, spec)) != 0)
+ goto fail1;
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_ipv4_udp_full(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_udp,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
+ tbl_id = falconsiena_filter_tbl_id(fs_spec.fsfs_type);
+ fsftp = &fsfp->fsf_tbl[tbl_id];
- spec->efs_type = EFX_FILTER_TX_UDP_FULL;
- spec->efs_flags = 0;
- spec->efs_dword[0] = src_udp | src_ip << 16;
- spec->efs_dword[1] = dest_udp << 16 | src_ip >> 16;
- spec->efs_dword[2] = dest_ip;
-}
-#endif /* EFSYS_OPT_SIENA */
+ if (fsftp->fsft_size == 0) {
+ rc = EINVAL;
+ goto fail2;
+ }
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_ipv4_udp_wild(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_udp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
+ key = falconsiena_filter_build(&filter, &fs_spec);
+
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ rc = falconsiena_filter_search(fsftp, &fs_spec, key, B_TRUE,
+ &filter_idx, &depth);
+ if (rc != 0)
+ goto fail3;
+
+ EFSYS_ASSERT3U(filter_idx, <, fsftp->fsft_size);
+ saved_fs_spec = &fsftp->fsft_spec[filter_idx];
+
+ if (falconsiena_filter_test_used(fsftp, filter_idx)) {
+ if (may_replace == B_FALSE) {
+ rc = EEXIST;
+ goto fail4;
+ }
+ }
+ falconsiena_filter_set_used(fsftp, filter_idx);
+ *saved_fs_spec = fs_spec;
+
+ if (fsfp->fsf_depth[fs_spec.fsfs_type] < depth) {
+ fsfp->fsf_depth[fs_spec.fsfs_type] = depth;
+ if (tbl_id == EFX_FS_FILTER_TBL_TX_IP ||
+ tbl_id == EFX_FS_FILTER_TBL_TX_MAC)
+ falconsiena_filter_push_tx_limits(enp);
+ else
+ falconsiena_filter_push_rx_limits(enp);
+ }
+
+ falconsiena_filter_push_entry(enp, fs_spec.fsfs_type,
+ filter_idx, &filter);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
- spec->efs_type = EFX_FILTER_TX_UDP_WILD;
- spec->efs_flags = 0;
- spec->efs_dword[0] = src_udp;
- spec->efs_dword[1] = 0;
- spec->efs_dword[2] = src_ip;
+fail3:
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ EFSYS_PROBE(fail3);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
}
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_mac_full(
- __inout efx_filter_spec_t *spec,
- __in uint16_t vlan_id,
- __in uint8_t *src_mac)
+static __checkReturn int
+falconsiena_filter_delete(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec)
{
+ int rc;
+ falconsiena_filter_spec_t fs_spec;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_id_t tbl_id;
+ falconsiena_filter_tbl_t *fsftp;
+ falconsiena_filter_spec_t *saved_spec;
+ efx_oword_t filter;
+ int filter_idx;
+ unsigned int depth;
+ int state;
+ uint32_t key;
+
EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(src_mac, !=, NULL);
-
- spec->efs_type = EFX_FILTER_TX_MAC_FULL;
- spec->efs_flags = 0;
- spec->efs_dword[0] = vlan_id;
- spec->efs_dword[1] =
- src_mac[2] << 24 |
- src_mac[3] << 16 |
- src_mac[4] << 8 |
- src_mac[5];
- spec->efs_dword[2] =
- src_mac[0] << 8 |
- src_mac[1];
+
+ if ((rc = falconsiena_filter_spec_from_gen_spec(&fs_spec, spec)) != 0)
+ goto fail1;
+
+ tbl_id = falconsiena_filter_tbl_id(fs_spec.fsfs_type);
+ fsftp = &fsfp->fsf_tbl[tbl_id];
+
+ key = falconsiena_filter_build(&filter, &fs_spec);
+
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ rc = falconsiena_filter_search(fsftp, &fs_spec, key, B_FALSE,
+ &filter_idx, &depth);
+ if (rc != 0)
+ goto fail2;
+
+ saved_spec = &fsftp->fsft_spec[filter_idx];
+
+ falconsiena_filter_clear_entry(enp, fsftp, filter_idx);
+ if (fsftp->fsft_used == 0)
+ falconsiena_filter_reset_search_depth(fsfp, tbl_id);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (0);
+
+fail2:
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
}
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_mac_wild(
- __inout efx_filter_spec_t *spec,
- __in uint8_t *src_mac)
+#define MAX_SUPPORTED 4
+
+static __checkReturn int
+falconsiena_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length)
{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(src_mac, !=, NULL);
-
- spec->efs_type = EFX_FILTER_TX_MAC_WILD;
- spec->efs_flags = 0;
- spec->efs_dword[0] = 0;
- spec->efs_dword[1] =
- src_mac[2] << 24 |
- src_mac[3] << 16 |
- src_mac[4] << 8 |
- src_mac[5];
- spec->efs_dword[2] =
- src_mac[0] << 8 |
- src_mac[1];
+ int index = 0;
+ uint32_t rx_matches[MAX_SUPPORTED];
+ int rc;
+
+ if (list == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ rx_matches[index++] =
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+ EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
+
+ rx_matches[index++] =
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT;
+
+ if (enp->en_features & EFX_FEATURE_MAC_HEADER_FILTERS) {
+ rx_matches[index++] =
+ EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC;
+
+ rx_matches[index++] = EFX_FILTER_MATCH_LOC_MAC;
+ }
+
+ EFSYS_ASSERT3U(index, <=, MAX_SUPPORTED);
+
+ *length = index;
+ memcpy(list, rx_matches, *length);
+
+ return (0);
+
+fail1:
+
+ return (rc);
}
-#endif /* EFSYS_OPT_SIENA */
+#undef MAX_SUPPORTED
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
#endif /* EFSYS_OPT_FILTER */
diff --git a/sys/dev/sfxge/common/efx_hash.c b/sys/dev/sfxge/common/efx_hash.c
new file mode 100644
index 000000000000..3005c1bb4738
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_hash.c
@@ -0,0 +1,333 @@
+/*-
+ * Copyright 2006 Bob Jenkins
+ *
+ * Derived from public domain source, see
+ * <http://burtleburtle.net/bob/c/lookup3.c>:
+ *
+ * "lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+ *
+ * These are functions for producing 32-bit hashes for hash table lookup...
+ * ...You can use this free for any purpose. It's in the public domain.
+ * It has no warranty."
+ *
+ * Copyright (c) 2014-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_impl.h"
+
+/* Hash initial value */
+#define EFX_HASH_INITIAL_VALUE 0xdeadbeef
+
+/*
+ * Rotate a 32-bit value left
+ *
+ * Allow platform to provide an intrinsic or optimised routine and
+ * fall-back to a simple shift based implementation.
+ */
+#if EFSYS_HAS_ROTL_DWORD
+
+#define EFX_HASH_ROTATE(_value, _shift) \
+ EFSYS_ROTL_DWORD(_value, _shift)
+
+#else
+
+#define EFX_HASH_ROTATE(_value, _shift) \
+ (((_value) << (_shift)) | ((_value) >> (32 - (_shift))))
+
+#endif
+
+/* Mix three 32-bit values reversibly */
+#define EFX_HASH_MIX(_a, _b, _c) \
+ do { \
+ _a -= _c; \
+ _a ^= EFX_HASH_ROTATE(_c, 4); \
+ _c += _b; \
+ _b -= _a; \
+ _b ^= EFX_HASH_ROTATE(_a, 6); \
+ _a += _c; \
+ _c -= _b; \
+ _c ^= EFX_HASH_ROTATE(_b, 8); \
+ _b += _a; \
+ _a -= _c; \
+ _a ^= EFX_HASH_ROTATE(_c, 16); \
+ _c += _b; \
+ _b -= _a; \
+ _b ^= EFX_HASH_ROTATE(_a, 19); \
+ _a += _c; \
+ _c -= _b; \
+ _c ^= EFX_HASH_ROTATE(_b, 4); \
+ _b += _a; \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
+/* Final mixing of three 32-bit values into one (_c) */
+#define EFX_HASH_FINALISE(_a, _b, _c) \
+ do { \
+ _c ^= _b; \
+ _c -= EFX_HASH_ROTATE(_b, 14); \
+ _a ^= _c; \
+ _a -= EFX_HASH_ROTATE(_c, 11); \
+ _b ^= _a; \
+ _b -= EFX_HASH_ROTATE(_a, 25); \
+ _c ^= _b; \
+ _c -= EFX_HASH_ROTATE(_b, 16); \
+ _a ^= _c; \
+ _a -= EFX_HASH_ROTATE(_c, 4); \
+ _b ^= _a; \
+ _b -= EFX_HASH_ROTATE(_a, 14); \
+ _c ^= _b; \
+ _c -= EFX_HASH_ROTATE(_b, 24); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
+
+/* Produce a 32-bit hash from 32-bit aligned input */
+ __checkReturn uint32_t
+efx_hash_dwords(
+ __in_ecount(count) uint32_t const *input,
+ __in size_t count,
+ __in uint32_t init)
+{
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+
+ /* Set up the initial internal state */
+ a = b = c = EFX_HASH_INITIAL_VALUE +
+ (((uint32_t)count) * sizeof (uint32_t)) + init;
+
+ /* Handle all but the last three dwords of the input */
+ while (count > 3) {
+ a += input[0];
+ b += input[1];
+ c += input[2];
+ EFX_HASH_MIX(a, b, c);
+
+ count -= 3;
+ input += 3;
+ }
+
+ /* Handle the left-overs */
+ switch (count) {
+ case 3:
+ c += input[2];
+ /* Fall-through */
+ case 2:
+ b += input[1];
+ /* Fall-through */
+ case 1:
+ a += input[0];
+ EFX_HASH_FINALISE(a, b, c);
+ break;
+
+ case 0:
+ /* Should only get here if count parameter was zero */
+ break;
+ }
+
+ return (c);
+}
+
+#if EFSYS_IS_BIG_ENDIAN
+
+/* Produce a 32-bit hash from arbitrarily aligned input */
+ __checkReturn uint32_t
+efx_hash_bytes(
+ __in_ecount(length) uint8_t const *input,
+ __in size_t length,
+ __in uint32_t init)
+{
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+
+ /* Set up the initial internal state */
+ a = b = c = EFX_HASH_INITIAL_VALUE + (uint32_t)length + init;
+
+ /* Handle all but the last twelve bytes of the input */
+ while (length > 12) {
+ a += ((uint32_t)input[0]) << 24;
+ a += ((uint32_t)input[1]) << 16;
+ a += ((uint32_t)input[2]) << 8;
+ a += ((uint32_t)input[3]);
+ b += ((uint32_t)input[4]) << 24;
+ b += ((uint32_t)input[5]) << 16;
+ b += ((uint32_t)input[6]) << 8;
+ b += ((uint32_t)input[7]);
+ c += ((uint32_t)input[8]) << 24;
+ c += ((uint32_t)input[9]) << 16;
+ c += ((uint32_t)input[10]) << 8;
+ c += ((uint32_t)input[11]);
+ EFX_HASH_MIX(a, b, c);
+ length -= 12;
+ input += 12;
+ }
+
+ /* Handle the left-overs */
+ switch (length) {
+ case 12:
+ c += ((uint32_t)input[11]);
+ /* Fall-through */
+ case 11:
+ c += ((uint32_t)input[10]) << 8;
+ /* Fall-through */
+ case 10:
+ c += ((uint32_t)input[9]) << 16;
+ /* Fall-through */
+ case 9:
+ c += ((uint32_t)input[8]) << 24;
+ /* Fall-through */
+ case 8:
+ b += ((uint32_t)input[7]);
+ /* Fall-through */
+ case 7:
+ b += ((uint32_t)input[6]) << 8;
+ /* Fall-through */
+ case 6:
+ b += ((uint32_t)input[5]) << 16;
+ /* Fall-through */
+ case 5:
+ b += ((uint32_t)input[4]) << 24;
+ /* Fall-through */
+ case 4:
+ a += ((uint32_t)input[3]);
+ /* Fall-through */
+ case 3:
+ a += ((uint32_t)input[2]) << 8;
+ /* Fall-through */
+ case 2:
+ a += ((uint32_t)input[1]) << 16;
+ /* Fall-through */
+ case 1:
+ a += ((uint32_t)input[0]) << 24;
+ EFX_HASH_FINALISE(a, b, c);
+ break;
+
+ case 0:
+ /* Should only get here if length parameter was zero */
+ break;
+ }
+
+ return (c);
+}
+
+#elif EFSYS_IS_LITTLE_ENDIAN
+
+/* Produce a 32-bit hash from arbitrarily aligned input */
+ __checkReturn uint32_t
+efx_hash_bytes(
+ __in_ecount(length) uint8_t const *input,
+ __in size_t length,
+ __in uint32_t init)
+{
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+
+ /* Set up the initial internal state */
+ a = b = c = EFX_HASH_INITIAL_VALUE + (uint32_t)length + init;
+
+ /* Handle all but the last twelve bytes of the input */
+ while (length > 12) {
+ a += ((uint32_t)input[0]);
+ a += ((uint32_t)input[1]) << 8;
+ a += ((uint32_t)input[2]) << 16;
+ a += ((uint32_t)input[3]) << 24;
+ b += ((uint32_t)input[4]);
+ b += ((uint32_t)input[5]) << 8;
+ b += ((uint32_t)input[6]) << 16;
+ b += ((uint32_t)input[7]) << 24;
+ c += ((uint32_t)input[8]);
+ c += ((uint32_t)input[9]) << 8;
+ c += ((uint32_t)input[10]) << 16;
+ c += ((uint32_t)input[11]) << 24;
+ EFX_HASH_MIX(a, b, c);
+ length -= 12;
+ input += 12;
+ }
+
+ /* Handle the left-overs */
+ switch (length) {
+ case 12:
+ c += ((uint32_t)input[11]) << 24;
+ /* Fall-through */
+ case 11:
+ c += ((uint32_t)input[10]) << 16;
+ /* Fall-through */
+ case 10:
+ c += ((uint32_t)input[9]) << 8;
+ /* Fall-through */
+ case 9:
+ c += ((uint32_t)input[8]);
+ /* Fall-through */
+ case 8:
+ b += ((uint32_t)input[7]) << 24;
+ /* Fall-through */
+ case 7:
+ b += ((uint32_t)input[6]) << 16;
+ /* Fall-through */
+ case 6:
+ b += ((uint32_t)input[5]) << 8;
+ /* Fall-through */
+ case 5:
+ b += ((uint32_t)input[4]);
+ /* Fall-through */
+ case 4:
+ a += ((uint32_t)input[3]) << 24;
+ /* Fall-through */
+ case 3:
+ a += ((uint32_t)input[2]) << 16;
+ /* Fall-through */
+ case 2:
+ a += ((uint32_t)input[1]) << 8;
+ /* Fall-through */
+ case 1:
+ a += ((uint32_t)input[0]);
+ EFX_HASH_FINALISE(a, b, c);
+ break;
+
+ case 0:
+ /* Should only get here if length parameter was zero */
+ break;
+ }
+
+ return (c);
+}
+
+#else
+
+#error "Neither of EFSYS_IS_{BIG,LITTLE}_ENDIAN is set"
+
+#endif
diff --git a/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h
index e7c2231b52fc..6f72d5fe2c38 100644
--- a/sys/dev/sfxge/common/efx_impl.h
+++ b/sys/dev/sfxge/common/efx_impl.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -31,6 +36,15 @@
#include "efsys.h"
#include "efx.h"
#include "efx_regs.h"
+#include "efx_regs_ef10.h"
+
+/* FIXME: Add definition for driver generated software events */
+#ifndef ESE_DZ_EV_CODE_DRV_GEN_EV
+#define ESE_DZ_EV_CODE_DRV_GEN_EV FSE_AZ_EV_CODE_DRV_GEN_EV
+#endif
+
+#include "efx_check.h"
+
#if EFSYS_OPT_FALCON
#include "falcon_impl.h"
@@ -40,40 +54,138 @@
#include "siena_impl.h"
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+#include "hunt_impl.h"
+#endif /* EFSYS_OPT_HUNTINGTON */
+
#ifdef __cplusplus
extern "C" {
#endif
-#define EFX_MOD_MCDI 0x00000001
-#define EFX_MOD_PROBE 0x00000002
-#define EFX_MOD_NVRAM 0x00000004
-#define EFX_MOD_VPD 0x00000008
-#define EFX_MOD_NIC 0x00000010
-#define EFX_MOD_INTR 0x00000020
-#define EFX_MOD_EV 0x00000040
-#define EFX_MOD_RX 0x00000080
-#define EFX_MOD_TX 0x00000100
-#define EFX_MOD_PORT 0x00000200
-#define EFX_MOD_MON 0x00000400
-#define EFX_MOD_WOL 0x00000800
-#define EFX_MOD_FILTER 0x00001000
-
-#define EFX_RESET_MAC 0x00000001
-#define EFX_RESET_PHY 0x00000002
+#define EFX_MOD_MCDI 0x00000001
+#define EFX_MOD_PROBE 0x00000002
+#define EFX_MOD_NVRAM 0x00000004
+#define EFX_MOD_VPD 0x00000008
+#define EFX_MOD_NIC 0x00000010
+#define EFX_MOD_INTR 0x00000020
+#define EFX_MOD_EV 0x00000040
+#define EFX_MOD_RX 0x00000080
+#define EFX_MOD_TX 0x00000100
+#define EFX_MOD_PORT 0x00000200
+#define EFX_MOD_MON 0x00000400
+#define EFX_MOD_WOL 0x00000800
+#define EFX_MOD_FILTER 0x00001000
+#define EFX_MOD_PKTFILTER 0x00002000
+
+#define EFX_RESET_MAC 0x00000001
+#define EFX_RESET_PHY 0x00000002
+#define EFX_RESET_RXQ_ERR 0x00000004
+#define EFX_RESET_TXQ_ERR 0x00000008
typedef enum efx_mac_type_e {
EFX_MAC_INVALID = 0,
EFX_MAC_FALCON_GMAC,
EFX_MAC_FALCON_XMAC,
EFX_MAC_SIENA,
+ EFX_MAC_HUNTINGTON,
EFX_MAC_NTYPES
} efx_mac_type_t;
+typedef struct efx_ev_ops_s {
+ int (*eevo_init)(efx_nic_t *);
+ void (*eevo_fini)(efx_nic_t *);
+ int (*eevo_qcreate)(efx_nic_t *, unsigned int,
+ efsys_mem_t *, size_t, uint32_t,
+ efx_evq_t *);
+ void (*eevo_qdestroy)(efx_evq_t *);
+ int (*eevo_qprime)(efx_evq_t *, unsigned int);
+ void (*eevo_qpost)(efx_evq_t *, uint16_t);
+ int (*eevo_qmoderate)(efx_evq_t *, unsigned int);
+#if EFSYS_OPT_QSTATS
+ void (*eevo_qstats_update)(efx_evq_t *, efsys_stat_t *);
+#endif
+} efx_ev_ops_t;
+
+typedef struct efx_tx_ops_s {
+ int (*etxo_init)(efx_nic_t *);
+ void (*etxo_fini)(efx_nic_t *);
+ int (*etxo_qcreate)(efx_nic_t *,
+ unsigned int, unsigned int,
+ efsys_mem_t *, size_t,
+ uint32_t, uint16_t,
+ efx_evq_t *, efx_txq_t *,
+ unsigned int *);
+ void (*etxo_qdestroy)(efx_txq_t *);
+ int (*etxo_qpost)(efx_txq_t *, efx_buffer_t *,
+ unsigned int, unsigned int,
+ unsigned int *);
+ void (*etxo_qpush)(efx_txq_t *, unsigned int, unsigned int);
+ int (*etxo_qpace)(efx_txq_t *, unsigned int);
+ int (*etxo_qflush)(efx_txq_t *);
+ void (*etxo_qenable)(efx_txq_t *);
+ int (*etxo_qpio_enable)(efx_txq_t *);
+ void (*etxo_qpio_disable)(efx_txq_t *);
+ int (*etxo_qpio_write)(efx_txq_t *,uint8_t *, size_t,
+ size_t);
+ int (*etxo_qpio_post)(efx_txq_t *, size_t, unsigned int,
+ unsigned int *);
+ int (*etxo_qdesc_post)(efx_txq_t *, efx_desc_t *,
+ unsigned int, unsigned int,
+ unsigned int *);
+ void (*etxo_qdesc_dma_create)(efx_txq_t *, efsys_dma_addr_t,
+ size_t, boolean_t,
+ efx_desc_t *);
+ void (*etxo_qdesc_tso_create)(efx_txq_t *, uint16_t,
+ uint32_t, uint8_t,
+ efx_desc_t *);
+ void (*etxo_qdesc_vlantci_create)(efx_txq_t *, uint16_t,
+ efx_desc_t *);
+#if EFSYS_OPT_QSTATS
+ void (*etxo_qstats_update)(efx_txq_t *,
+ efsys_stat_t *);
+#endif
+} efx_tx_ops_t;
+
+typedef struct efx_rx_ops_s {
+ int (*erxo_init)(efx_nic_t *);
+ void (*erxo_fini)(efx_nic_t *);
+#if EFSYS_OPT_RX_HDR_SPLIT
+ int (*erxo_hdr_split_enable)(efx_nic_t *, unsigned int,
+ unsigned int);
+#endif
+#if EFSYS_OPT_RX_SCATTER
+ int (*erxo_scatter_enable)(efx_nic_t *, unsigned int);
+#endif
+#if EFSYS_OPT_RX_SCALE
+ int (*erxo_scale_mode_set)(efx_nic_t *, efx_rx_hash_alg_t,
+ efx_rx_hash_type_t, boolean_t);
+ int (*erxo_scale_key_set)(efx_nic_t *, uint8_t *, size_t);
+ int (*erxo_scale_tbl_set)(efx_nic_t *, unsigned int *,
+ size_t);
+#endif
+ void (*erxo_qpost)(efx_rxq_t *, efsys_dma_addr_t *, size_t,
+ unsigned int, unsigned int,
+ unsigned int);
+ void (*erxo_qpush)(efx_rxq_t *, unsigned int, unsigned int *);
+ int (*erxo_qflush)(efx_rxq_t *);
+ void (*erxo_qenable)(efx_rxq_t *);
+ int (*erxo_qcreate)(efx_nic_t *enp, unsigned int,
+ unsigned int, efx_rxq_type_t,
+ efsys_mem_t *, size_t, uint32_t,
+ efx_evq_t *, efx_rxq_t *);
+ void (*erxo_qdestroy)(efx_rxq_t *);
+} efx_rx_ops_t;
+
typedef struct efx_mac_ops_s {
int (*emo_reset)(efx_nic_t *); /* optional */
int (*emo_poll)(efx_nic_t *, efx_link_mode_t *);
int (*emo_up)(efx_nic_t *, boolean_t *);
+ int (*emo_addr_set)(efx_nic_t *);
int (*emo_reconfigure)(efx_nic_t *);
+ int (*emo_multicast_list_set)(efx_nic_t *);
+ int (*emo_filter_default_rxq_set)(efx_nic_t *,
+ efx_rxq_t *, boolean_t);
+ void (*emo_filter_default_rxq_clear)(efx_nic_t *);
#if EFSYS_OPT_LOOPBACK
int (*emo_loopback_set)(efx_nic_t *, efx_link_mode_t,
efx_loopback_type_t);
@@ -103,21 +215,59 @@ typedef struct efx_phy_ops_s {
#endif /* EFSYS_OPT_PHY_STATS */
#if EFSYS_OPT_PHY_PROPS
#if EFSYS_OPT_NAMES
- const char __cs *(*epo_prop_name)(efx_nic_t *, unsigned int);
+ const char *(*epo_prop_name)(efx_nic_t *, unsigned int);
#endif /* EFSYS_OPT_PHY_PROPS */
int (*epo_prop_get)(efx_nic_t *, unsigned int, uint32_t,
uint32_t *);
int (*epo_prop_set)(efx_nic_t *, unsigned int, uint32_t);
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
- int (*epo_bist_start)(efx_nic_t *, efx_phy_bist_type_t);
- int (*epo_bist_poll)(efx_nic_t *, efx_phy_bist_type_t,
- efx_phy_bist_result_t *, uint32_t *,
+#if EFSYS_OPT_BIST
+ int (*epo_bist_enable_offline)(efx_nic_t *);
+ int (*epo_bist_start)(efx_nic_t *, efx_bist_type_t);
+ int (*epo_bist_poll)(efx_nic_t *, efx_bist_type_t,
+ efx_bist_result_t *, uint32_t *,
unsigned long *, size_t);
- void (*epo_bist_stop)(efx_nic_t *, efx_phy_bist_type_t);
-#endif /* EFSYS_OPT_PHY_BIST */
+ void (*epo_bist_stop)(efx_nic_t *, efx_bist_type_t);
+#endif /* EFSYS_OPT_BIST */
} efx_phy_ops_t;
+#if EFSYS_OPT_FILTER
+typedef struct efx_filter_ops_s {
+ int (*efo_init)(efx_nic_t *);
+ void (*efo_fini)(efx_nic_t *);
+ int (*efo_restore)(efx_nic_t *);
+ int (*efo_add)(efx_nic_t *, efx_filter_spec_t *,
+ boolean_t may_replace);
+ int (*efo_delete)(efx_nic_t *, efx_filter_spec_t *);
+ int (*efo_supported_filters)(efx_nic_t *, uint32_t *, size_t *);
+ int (*efo_reconfigure)(efx_nic_t *, uint8_t const *, boolean_t,
+ boolean_t, boolean_t, boolean_t,
+ uint8_t const *, int);
+} efx_filter_ops_t;
+
+extern __checkReturn int
+efx_filter_reconfigure(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *mac_addr,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count);
+
+#endif /* EFSYS_OPT_FILTER */
+
+typedef struct efx_pktfilter_ops_s {
+ int (*epfo_set)(efx_nic_t *,
+ boolean_t unicst,
+ boolean_t brdcast);
+#if EFSYS_OPT_MCAST_FILTER_LIST
+ int (*epfo_mcast_list_set)(efx_nic_t *, uint8_t const *addrs, int count);
+#endif /* EFSYS_OPT_MCAST_FILTER_LIST */
+ int (*epfo_mcast_all)(efx_nic_t *);
+} efx_pktfilter_ops_t;
+
typedef struct efx_port_s {
efx_mac_type_t ep_mac_type;
uint32_t ep_phy_type;
@@ -125,11 +275,16 @@ typedef struct efx_port_s {
uint32_t ep_mac_pdu;
uint8_t ep_mac_addr[6];
efx_link_mode_t ep_link_mode;
- boolean_t ep_unicst;
+ boolean_t ep_all_unicst;
+ boolean_t ep_mulcst;
+ boolean_t ep_all_mulcst;
boolean_t ep_brdcst;
unsigned int ep_fcntl;
boolean_t ep_fcntl_autoneg;
efx_oword_t ep_multicst_hash[2];
+ uint8_t ep_mulcst_addr_list[EFX_MAC_ADDR_LEN *
+ EFX_MAC_MULTICAST_LIST_MAX];
+ uint32_t ep_mulcst_addr_count;
#if EFSYS_OPT_LOOPBACK
efx_loopback_type_t ep_loopback_type;
efx_link_mode_t ep_loopback_link_mode;
@@ -161,8 +316,8 @@ typedef struct efx_port_s {
uint32_t ep_fwver; /* falcon only */
boolean_t ep_mac_drain;
boolean_t ep_mac_stats_pending;
-#if EFSYS_OPT_PHY_BIST
- efx_phy_bist_type_t ep_current_bist;
+#if EFSYS_OPT_BIST
+ efx_bist_type_t ep_current_bist;
#endif
efx_mac_ops_t *ep_emop;
efx_phy_ops_t *ep_epop;
@@ -182,16 +337,30 @@ typedef struct efx_mon_s {
efx_mon_ops_t *em_emop;
} efx_mon_t;
+typedef struct efx_intr_ops_s {
+ int (*eio_init)(efx_nic_t *, efx_intr_type_t, efsys_mem_t *);
+ void (*eio_enable)(efx_nic_t *);
+ void (*eio_disable)(efx_nic_t *);
+ void (*eio_disable_unlocked)(efx_nic_t *);
+ int (*eio_trigger)(efx_nic_t *, unsigned int);
+ void (*eio_fini)(efx_nic_t *);
+} efx_intr_ops_t;
+
typedef struct efx_intr_s {
- efx_intr_type_t ei_type;
+ efx_intr_ops_t *ei_eiop;
efsys_mem_t *ei_esmp;
+ efx_intr_type_t ei_type;
unsigned int ei_level;
} efx_intr_t;
typedef struct efx_nic_ops_s {
int (*eno_probe)(efx_nic_t *);
+ int (*eno_set_drv_limits)(efx_nic_t *, efx_drv_limits_t*);
int (*eno_reset)(efx_nic_t *);
int (*eno_init)(efx_nic_t *);
+ int (*eno_get_vi_pool)(efx_nic_t *, uint32_t *);
+ int (*eno_get_bar_region)(efx_nic_t *, efx_nic_region_t,
+ uint32_t *, size_t *);
#if EFSYS_OPT_DIAG
int (*eno_sram_test)(efx_nic_t *, efx_sram_pattern_fn_t);
int (*eno_register_test)(efx_nic_t *);
@@ -201,94 +370,107 @@ typedef struct efx_nic_ops_s {
} efx_nic_ops_t;
#ifndef EFX_TXQ_LIMIT_TARGET
-# define EFX_TXQ_LIMIT_TARGET 259
+#define EFX_TXQ_LIMIT_TARGET 259
#endif
#ifndef EFX_RXQ_LIMIT_TARGET
-# define EFX_RXQ_LIMIT_TARGET 512
+#define EFX_RXQ_LIMIT_TARGET 512
#endif
#ifndef EFX_TXQ_DC_SIZE
-#define EFX_TXQ_DC_SIZE 1 /* 16 descriptors */
+#define EFX_TXQ_DC_SIZE 1 /* 16 descriptors */
#endif
#ifndef EFX_RXQ_DC_SIZE
-#define EFX_RXQ_DC_SIZE 3 /* 64 descriptors */
+#define EFX_RXQ_DC_SIZE 3 /* 64 descriptors */
#endif
#if EFSYS_OPT_FILTER
-typedef enum efx_filter_type_e {
- EFX_FILTER_RX_TCP_FULL, /* TCP/IPv4 4-tuple {dIP,dTCP,sIP,sTCP} */
- EFX_FILTER_RX_TCP_WILD, /* TCP/IPv4 dest {dIP,dTCP, -, -} */
- EFX_FILTER_RX_UDP_FULL, /* UDP/IPv4 4-tuple {dIP,dUDP,sIP,sUDP} */
- EFX_FILTER_RX_UDP_WILD, /* UDP/IPv4 dest {dIP,dUDP, -, -} */
+typedef struct falconsiena_filter_spec_s {
+ uint8_t fsfs_type;
+ uint32_t fsfs_flags;
+ uint32_t fsfs_dmaq_id;
+ uint32_t fsfs_dword[3];
+} falconsiena_filter_spec_t;
+
+typedef enum falconsiena_filter_type_e {
+ EFX_FS_FILTER_RX_TCP_FULL, /* TCP/IPv4 4-tuple {dIP,dTCP,sIP,sTCP} */
+ EFX_FS_FILTER_RX_TCP_WILD, /* TCP/IPv4 dest {dIP,dTCP, -, -} */
+ EFX_FS_FILTER_RX_UDP_FULL, /* UDP/IPv4 4-tuple {dIP,dUDP,sIP,sUDP} */
+ EFX_FS_FILTER_RX_UDP_WILD, /* UDP/IPv4 dest {dIP,dUDP, -, -} */
#if EFSYS_OPT_SIENA
- EFX_FILTER_RX_MAC_FULL, /* Ethernet {dMAC,VLAN} */
- EFX_FILTER_RX_MAC_WILD, /* Ethernet {dMAC, -} */
+ EFX_FS_FILTER_RX_MAC_FULL, /* Ethernet {dMAC,VLAN} */
+ EFX_FS_FILTER_RX_MAC_WILD, /* Ethernet {dMAC, -} */
- EFX_FILTER_TX_TCP_FULL, /* TCP/IPv4 {dIP,dTCP,sIP,sTCP} */
- EFX_FILTER_TX_TCP_WILD, /* TCP/IPv4 { -, -,sIP,sTCP} */
- EFX_FILTER_TX_UDP_FULL, /* UDP/IPv4 {dIP,dTCP,sIP,sTCP} */
- EFX_FILTER_TX_UDP_WILD, /* UDP/IPv4 source (host, port) */
+ EFX_FS_FILTER_TX_TCP_FULL, /* TCP/IPv4 {dIP,dTCP,sIP,sTCP} */
+ EFX_FS_FILTER_TX_TCP_WILD, /* TCP/IPv4 { -, -,sIP,sTCP} */
+ EFX_FS_FILTER_TX_UDP_FULL, /* UDP/IPv4 {dIP,dTCP,sIP,sTCP} */
+ EFX_FS_FILTER_TX_UDP_WILD, /* UDP/IPv4 source (host, port) */
- EFX_FILTER_TX_MAC_FULL, /* Ethernet source (MAC address, VLAN ID) */
- EFX_FILTER_TX_MAC_WILD, /* Ethernet source (MAC address) */
+ EFX_FS_FILTER_TX_MAC_FULL, /* Ethernet source (MAC address, VLAN ID) */
+ EFX_FS_FILTER_TX_MAC_WILD, /* Ethernet source (MAC address) */
#endif /* EFSYS_OPT_SIENA */
- EFX_FILTER_NTYPES
-} efx_filter_type_t;
-
-typedef enum efx_filter_tbl_id_e {
- EFX_FILTER_TBL_RX_IP = 0,
- EFX_FILTER_TBL_RX_MAC,
- EFX_FILTER_TBL_TX_IP,
- EFX_FILTER_TBL_TX_MAC,
- EFX_FILTER_NTBLS
-} efx_filter_tbl_id_t;
-
-typedef struct efx_filter_tbl_s {
- int eft_size; /* number of entries */
- int eft_used; /* active count */
- uint32_t *eft_bitmap; /* active bitmap */
- efx_filter_spec_t *eft_spec; /* array of saved specs */
-} efx_filter_tbl_t;
+ EFX_FS_FILTER_NTYPES
+} falconsiena_filter_type_t;
+
+typedef enum falconsiena_filter_tbl_id_e {
+ EFX_FS_FILTER_TBL_RX_IP = 0,
+ EFX_FS_FILTER_TBL_RX_MAC,
+ EFX_FS_FILTER_TBL_TX_IP,
+ EFX_FS_FILTER_TBL_TX_MAC,
+ EFX_FS_FILTER_NTBLS
+} falconsiena_filter_tbl_id_t;
+
+typedef struct falconsiena_filter_tbl_s {
+ int fsft_size; /* number of entries */
+ int fsft_used; /* active count */
+ uint32_t *fsft_bitmap; /* active bitmap */
+ falconsiena_filter_spec_t *fsft_spec; /* array of saved specs */
+} falconsiena_filter_tbl_t;
+
+typedef struct falconsiena_filter_s {
+ falconsiena_filter_tbl_t fsf_tbl[EFX_FS_FILTER_NTBLS];
+ unsigned int fsf_depth[EFX_FS_FILTER_NTYPES];
+} falconsiena_filter_t;
typedef struct efx_filter_s {
- efx_filter_tbl_t ef_tbl[EFX_FILTER_NTBLS];
- unsigned int ef_depth[EFX_FILTER_NTYPES];
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+ falconsiena_filter_t *ef_falconsiena_filter;
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ hunt_filter_table_t *ef_hunt_filter_table;
+#endif /* EFSYS_OPT_HUNTINGTON */
} efx_filter_t;
-
-extern __checkReturn int
-efx_filter_insert_filter(
- __in efx_nic_t *enp,
- __in efx_filter_spec_t *spec,
- __in boolean_t replace);
-
-extern __checkReturn int
-efx_filter_remove_filter(
- __in efx_nic_t *enp,
- __in efx_filter_spec_t *spec);
-
-extern void
-efx_filter_remove_index(
- __inout efx_nic_t *enp,
- __in efx_filter_type_t type,
- __in int filter_idx);
-
extern void
-efx_filter_redirect_index(
- __inout efx_nic_t *enp,
- __in efx_filter_type_t type,
- __in int filter_index,
- __in int rxq_index);
-
-extern __checkReturn int
-efx_filter_clear_tbl(
+falconsiena_filter_tbl_clear(
__in efx_nic_t *enp,
- __in efx_filter_tbl_id_t tbl);
+ __in falconsiena_filter_tbl_id_t tbl);
#endif /* EFSYS_OPT_FILTER */
+#if EFSYS_OPT_MCDI
+
+typedef struct efx_mcdi_ops_s {
+ int (*emco_init)(efx_nic_t *, const efx_mcdi_transport_t *);
+ void (*emco_request_copyin)(efx_nic_t *, efx_mcdi_req_t *,
+ unsigned int, boolean_t, boolean_t);
+ boolean_t (*emco_request_poll)(efx_nic_t *);
+ void (*emco_request_copyout)(efx_nic_t *, efx_mcdi_req_t *);
+ int (*emco_poll_reboot)(efx_nic_t *);
+ void (*emco_fini)(efx_nic_t *);
+ int (*emco_fw_update_supported)(efx_nic_t *, boolean_t *);
+ int (*emco_macaddr_change_supported)(efx_nic_t *, boolean_t *);
+} efx_mcdi_ops_t;
+
+typedef struct efx_mcdi_s {
+ efx_mcdi_ops_t *em_emcop;
+ const efx_mcdi_transport_t *em_emtp;
+ efx_mcdi_iface_t em_emip;
+} efx_mcdi_t;
+
+#endif /* EFSYS_OPT_MCDI */
+
#if EFSYS_OPT_NVRAM
typedef struct efx_nvram_ops_s {
#if EFSYS_OPT_DIAG
@@ -325,6 +507,85 @@ typedef struct efx_vpd_ops_s {
} efx_vpd_ops_t;
#endif /* EFSYS_OPT_VPD */
+#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
+
+ __checkReturn int
+efx_mcdi_nvram_partitions(
+ __in efx_nic_t *enp,
+ __out_bcount(size) caddr_t data,
+ __in size_t size,
+ __out unsigned int *npartnp);
+
+ __checkReturn int
+efx_mcdi_nvram_metadata(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4],
+ __out_bcount_opt(size) char *descp,
+ __in size_t size);
+
+ __checkReturn int
+efx_mcdi_nvram_info(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __out_opt size_t *sizep,
+ __out_opt uint32_t *addressp,
+ __out_opt uint32_t *erase_sizep);
+
+ __checkReturn int
+efx_mcdi_nvram_update_start(
+ __in efx_nic_t *enp,
+ __in uint32_t partn);
+
+ __checkReturn int
+efx_mcdi_nvram_read(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+ __checkReturn int
+efx_mcdi_nvram_erase(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __in size_t size);
+
+ __checkReturn int
+efx_mcdi_nvram_write(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+ __checkReturn int
+efx_mcdi_nvram_update_finish(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in boolean_t reboot);
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+efx_mcdi_nvram_test(
+ __in efx_nic_t *enp,
+ __in uint32_t partn);
+
+#endif /* EFSYS_OPT_DIAG */
+
+#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
+
+typedef struct efx_drv_cfg_s {
+ uint32_t edc_min_vi_count;
+ uint32_t edc_max_vi_count;
+
+ uint32_t edc_max_piobuf_count;
+ uint32_t edc_pio_alloc_size;
+} efx_drv_cfg_t;
+
struct efx_nic_s {
uint32_t en_magic;
efx_family_t en_family;
@@ -335,6 +596,7 @@ struct efx_nic_s {
unsigned int en_mod_flags;
unsigned int en_reset_flags;
efx_nic_cfg_t en_nic_cfg;
+ efx_drv_cfg_t en_drv_cfg;
efx_port_t en_port;
efx_mon_t en_mon;
efx_intr_t en_intr;
@@ -342,9 +604,17 @@ struct efx_nic_s {
uint32_t en_rx_qcount;
uint32_t en_tx_qcount;
efx_nic_ops_t *en_enop;
+ efx_ev_ops_t *en_eevop;
+ efx_tx_ops_t *en_etxop;
+ efx_rx_ops_t *en_erxop;
#if EFSYS_OPT_FILTER
efx_filter_t en_filter;
+ efx_filter_ops_t *en_efop;
#endif /* EFSYS_OPT_FILTER */
+ efx_pktfilter_ops_t *en_epfop;
+#if EFSYS_OPT_MCDI
+ efx_mcdi_t en_mcdi;
+#endif /* EFSYS_OPT_MCDI */
#if EFSYS_OPT_NVRAM
efx_nvram_type_t en_nvram_locked;
efx_nvram_ops_t *en_envop;
@@ -352,6 +622,12 @@ struct efx_nic_s {
#if EFSYS_OPT_VPD
efx_vpd_ops_t *en_evpdop;
#endif /* EFSYS_OPT_VPD */
+#if EFSYS_OPT_RX_SCALE
+ efx_rx_hash_support_t en_hash_support;
+ efx_rx_scale_support_t en_rss_support;
+ uint32_t en_rss_context;
+#endif /* EFSYS_OPT_RX_SCALE */
+ uint32_t en_vport_id;
union {
#if EFSYS_OPT_FALCON
struct {
@@ -373,9 +649,6 @@ struct efx_nic_s {
#endif /* EFSYS_OPT_FALCON */
#if EFSYS_OPT_SIENA
struct {
-#if EFSYS_OPT_MCDI
- efx_mcdi_iface_t enu_mip;
-#endif /* EFSYS_OPT_MCDI */
#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
unsigned int enu_partn_mask;
#endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */
@@ -383,8 +656,28 @@ struct efx_nic_s {
caddr_t enu_svpd;
size_t enu_svpd_length;
#endif /* EFSYS_OPT_VPD */
+ int enu_unused;
} siena;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ struct {
+ int enu_vi_base;
+ int enu_vi_count;
+#if EFSYS_OPT_VPD
+ caddr_t enu_svpd;
+ size_t enu_svpd_length;
+#endif /* EFSYS_OPT_VPD */
+ efx_piobuf_handle_t enu_piobuf_handle[HUNT_PIOBUF_NBUFS];
+ uint32_t enu_piobuf_count;
+ uint32_t enu_pio_alloc_map[HUNT_PIOBUF_NBUFS];
+ uint32_t enu_pio_write_vi_base;
+ /* Memory BAR mapping regions */
+ uint32_t enu_uc_mem_map_offset;
+ size_t enu_uc_mem_map_size;
+ uint32_t enu_wc_mem_map_offset;
+ size_t enu_wc_mem_map_size;
+ } hunt;
+#endif /* EFSYS_OPT_HUNTINGTON */
} en_u;
};
@@ -394,6 +687,11 @@ struct efx_nic_s {
typedef boolean_t (*efx_ev_handler_t)(efx_evq_t *, efx_qword_t *,
const efx_ev_callbacks_t *, void *);
+typedef struct efx_evq_rxq_state_s {
+ unsigned int eers_rx_read_ptr;
+ unsigned int eers_rx_mask;
+} efx_evq_rxq_state_t;
+
struct efx_evq_s {
uint32_t ee_magic;
efx_nic_t *ee_enp;
@@ -403,7 +701,17 @@ struct efx_evq_s {
#if EFSYS_OPT_QSTATS
uint32_t ee_stat[EV_NQSTATS];
#endif /* EFSYS_OPT_QSTATS */
- efx_ev_handler_t ee_handler[1 << FSF_AZ_EV_CODE_WIDTH];
+
+ efx_ev_handler_t ee_rx;
+ efx_ev_handler_t ee_tx;
+ efx_ev_handler_t ee_driver;
+ efx_ev_handler_t ee_global;
+ efx_ev_handler_t ee_drv_gen;
+#if EFSYS_OPT_MCDI
+ efx_ev_handler_t ee_mcdi;
+#endif /* EFSYS_OPT_MCDI */
+
+ efx_evq_rxq_state_t ee_rxq_state[EFX_EV_RX_NLABELS];
};
#define EFX_EVQ_MAGIC 0x08081997
@@ -414,7 +722,9 @@ struct efx_evq_s {
struct efx_rxq_s {
uint32_t er_magic;
efx_nic_t *er_enp;
+ efx_evq_t *er_eep;
unsigned int er_index;
+ unsigned int er_label;
unsigned int er_mask;
efsys_mem_t *er_esmp;
};
@@ -427,6 +737,13 @@ struct efx_txq_s {
unsigned int et_index;
unsigned int et_mask;
efsys_mem_t *et_esmp;
+#if EFSYS_OPT_HUNTINGTON
+ uint32_t et_pio_bufnum;
+ uint32_t et_pio_blknum;
+ uint32_t et_pio_write_offset;
+ uint32_t et_pio_offset;
+ size_t et_pio_size;
+#endif
#if EFSYS_OPT_QSTATS
uint32_t et_stat[TX_NQSTATS];
#endif /* EFSYS_OPT_QSTATS */
@@ -445,10 +762,19 @@ struct efx_txq_s {
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
+#define EFX_MAC_BROADCAST_ADDR_SET(_dst) \
+ do { \
+ uint16_t *_d = (uint16_t *)(_dst); \
+ _d[0] = 0xffff; \
+ _d[1] = 0xffff; \
+ _d[2] = 0xffff; \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
#if EFSYS_OPT_CHECK_REG
#define EFX_CHECK_REG(_enp, _reg) \
do { \
- const char __cs *name = #_reg; \
+ const char *name = #_reg; \
char min = name[4]; \
char max = name[5]; \
char rev; \
@@ -462,6 +788,10 @@ struct efx_txq_s {
rev = 'C'; \
break; \
\
+ case EFX_FAMILY_HUNTINGTON: \
+ rev = 'D'; \
+ break; \
+ \
default: \
rev = '?'; \
break; \
@@ -578,6 +908,21 @@ struct efx_txq_s {
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
+#define EFX_BAR_TBL_WRITED2(_enp, _reg, _index, _edp, _lock) \
+ do { \
+ EFX_CHECK_REG((_enp), (_reg)); \
+ EFSYS_PROBE4(efx_bar_tbl_writed, const char *, #_reg, \
+ uint32_t, (_index), \
+ uint32_t, _reg ## _OFST, \
+ uint32_t, (_edp)->ed_u32[0]); \
+ EFSYS_BAR_WRITED((_enp)->en_esbp, \
+ (_reg ## _OFST + \
+ (2 * sizeof (efx_dword_t)) + \
+ ((_index) * _reg ## _STEP)), \
+ (_edp), (_lock)); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
#define EFX_BAR_TBL_WRITED3(_enp, _reg, _index, _edp, _lock) \
do { \
EFX_CHECK_REG((_enp), (_reg)); \
@@ -621,12 +966,12 @@ struct efx_txq_s {
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
-#define EFX_BAR_TBL_READO(_enp, _reg, _index, _eop) \
+#define EFX_BAR_TBL_READO(_enp, _reg, _index, _eop, _lock) \
do { \
EFX_CHECK_REG((_enp), (_reg)); \
EFSYS_BAR_READO((_enp)->en_esbp, \
(_reg ## _OFST + ((_index) * _reg ## _STEP)), \
- (_eop), B_TRUE); \
+ (_eop), (_lock)); \
EFSYS_PROBE7(efx_bar_tbl_reado, const char *, #_reg, \
uint32_t, (_index), \
uint32_t, _reg ## _OFST, \
@@ -637,7 +982,7 @@ struct efx_txq_s {
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
-#define EFX_BAR_TBL_WRITEO(_enp, _reg, _index, _eop) \
+#define EFX_BAR_TBL_WRITEO(_enp, _reg, _index, _eop, _lock) \
do { \
EFX_CHECK_REG((_enp), (_reg)); \
EFSYS_PROBE7(efx_bar_tbl_writeo, const char *, #_reg, \
@@ -649,14 +994,71 @@ struct efx_txq_s {
uint32_t, (_eop)->eo_u32[0]); \
EFSYS_BAR_WRITEO((_enp)->en_esbp, \
(_reg ## _OFST + ((_index) * _reg ## _STEP)), \
- (_eop), B_TRUE); \
+ (_eop), (_lock)); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
+/*
+ * Allow drivers to perform optimised 128-bit doorbell writes.
+ * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are
+ * special-cased in the BIU on the Falcon/Siena and EF10 architectures to avoid
+ * the need for locking in the host, and are the only ones known to be safe to
+ * use 128-bites write with.
+ */
+#define EFX_BAR_TBL_DOORBELL_WRITEO(_enp, _reg, _index, _eop) \
+ do { \
+ EFX_CHECK_REG((_enp), (_reg)); \
+ EFSYS_PROBE7(efx_bar_tbl_doorbell_writeo, \
+ const char *, \
+ #_reg, \
+ uint32_t, (_index), \
+ uint32_t, _reg ## _OFST, \
+ uint32_t, (_eop)->eo_u32[3], \
+ uint32_t, (_eop)->eo_u32[2], \
+ uint32_t, (_eop)->eo_u32[1], \
+ uint32_t, (_eop)->eo_u32[0]); \
+ EFSYS_BAR_DOORBELL_WRITEO((_enp)->en_esbp, \
+ (_reg ## _OFST + ((_index) * _reg ## _STEP)), \
+ (_eop)); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
+#define EFX_DMA_SYNC_QUEUE_FOR_DEVICE(_esmp, _entries, _wptr, _owptr) \
+ do { \
+ unsigned int _new = (_wptr); \
+ unsigned int _old = (_owptr); \
+ \
+ if ((_new) >= (_old)) \
+ EFSYS_DMA_SYNC_FOR_DEVICE((_esmp), \
+ (_old) * sizeof (efx_desc_t), \
+ ((_new) - (_old)) * sizeof (efx_desc_t)); \
+ else \
+ /* \
+ * It is cheaper to sync entire map than sync \
+ * two parts especially when offset/size are \
+ * ignored and entire map is synced in any case.\
+ */ \
+ EFSYS_DMA_SYNC_FOR_DEVICE((_esmp), \
+ 0, \
+ (_entries) * sizeof (efx_desc_t)); \
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
extern __checkReturn int
+efx_nic_biu_test(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
efx_mac_select(
__in efx_nic_t *enp);
+extern void
+efx_mac_multicast_hash_compute(
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count,
+ __out efx_oword_t *hash_low,
+ __out efx_oword_t *hash_high);
+
extern __checkReturn int
efx_phy_probe(
__in efx_nic_t *enp);
@@ -683,7 +1085,7 @@ efx_vpd_hunk_verify(
extern __checkReturn int
efx_vpd_hunk_reinit(
- __in caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size,
__in boolean_t wantpid);
@@ -716,7 +1118,7 @@ efx_vpd_hunk_set(
#if EFSYS_OPT_DIAG
-extern efx_sram_pattern_fn_t __cs __efx_sram_pattern_fns[];
+extern efx_sram_pattern_fn_t __efx_sram_pattern_fns[];
typedef struct efx_register_set_s {
unsigned int address;
@@ -740,6 +1142,23 @@ efx_nic_test_tables(
#endif /* EFSYS_OPT_DIAG */
+#if EFSYS_OPT_MCDI
+
+extern __checkReturn int
+efx_mcdi_set_workaround(
+ __in efx_nic_t *enp,
+ __in uint32_t type,
+ __in boolean_t enabled,
+ __out_opt uint32_t *flagsp);
+
+extern __checkReturn int
+efx_mcdi_get_workarounds(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *implementedp,
+ __out_opt uint32_t *enabledp);
+
+#endif /* EFSYS_OPT_MCDI */
+
#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/sfxge/common/efx_intr.c b/sys/dev/sfxge/common/efx_intr.c
index 556728df7ba9..d40f57f0b037 100644
--- a/sys/dev/sfxge/common/efx_intr.c
+++ b/sys/dev/sfxge/common/efx_intr.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -32,6 +37,82 @@ __FBSDID("$FreeBSD$");
#include "efx_regs.h"
#include "efx_impl.h"
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_intr_init(
+ __in efx_nic_t *enp,
+ __in efx_intr_type_t type,
+ __in efsys_mem_t *esmp);
+
+static void
+falconsiena_intr_enable(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_intr_disable(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_intr_disable_unlocked(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_intr_trigger(
+ __in efx_nic_t *enp,
+ __in unsigned int level);
+
+static void
+falconsiena_intr_fini(
+ __in efx_nic_t *enp);
+
+
+static __checkReturn boolean_t
+falconsiena_intr_check_fatal(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_intr_fatal(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+
+#if EFSYS_OPT_FALCON
+static efx_intr_ops_t __efx_intr_falcon_ops = {
+ falconsiena_intr_init, /* eio_init */
+ falconsiena_intr_enable, /* eio_enable */
+ falconsiena_intr_disable, /* eio_disable */
+ falconsiena_intr_disable_unlocked, /* eio_disable_unlocked */
+ falconsiena_intr_trigger, /* eio_trigger */
+ falconsiena_intr_fini, /* eio_fini */
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_intr_ops_t __efx_intr_siena_ops = {
+ falconsiena_intr_init, /* eio_init */
+ falconsiena_intr_enable, /* eio_enable */
+ falconsiena_intr_disable, /* eio_disable */
+ falconsiena_intr_disable_unlocked, /* eio_disable_unlocked */
+ falconsiena_intr_trigger, /* eio_trigger */
+ falconsiena_intr_fini, /* eio_fini */
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_intr_ops_t __efx_intr_hunt_ops = {
+ hunt_intr_init, /* eio_init */
+ hunt_intr_enable, /* eio_enable */
+ hunt_intr_disable, /* eio_disable */
+ hunt_intr_disable_unlocked, /* eio_disable_unlocked */
+ hunt_intr_trigger, /* eio_trigger */
+ hunt_intr_fini, /* eio_fini */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+
__checkReturn int
efx_intr_init(
__in efx_nic_t *enp,
@@ -39,7 +120,7 @@ efx_intr_init(
__in efsys_mem_t *esmp)
{
efx_intr_t *eip = &(enp->en_intr);
- efx_oword_t oword;
+ efx_intr_ops_t *eiop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -50,10 +131,219 @@ efx_intr_init(
goto fail1;
}
+ eip->ei_esmp = esmp;
+ eip->ei_type = type;
+ eip->ei_level = 0;
+
enp->en_mod_flags |= EFX_MOD_INTR;
- eip->ei_type = type;
- eip->ei_esmp = esmp;
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ eiop = (efx_intr_ops_t *)&__efx_intr_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ eiop = (efx_intr_ops_t *)&__efx_intr_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ eiop = (efx_intr_ops_t *)&__efx_intr_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ default:
+ EFSYS_ASSERT(B_FALSE);
+ rc = ENOTSUP;
+ goto fail2;
+ }
+
+ if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
+ goto fail3;
+
+ eip->ei_eiop = eiop;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_intr_fini(
+ __in efx_nic_t *enp)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ efx_intr_ops_t *eiop = eip->ei_eiop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+ eiop->eio_fini(enp);
+
+ enp->en_mod_flags &= ~EFX_MOD_INTR;
+}
+
+ void
+efx_intr_enable(
+ __in efx_nic_t *enp)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ efx_intr_ops_t *eiop = eip->ei_eiop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+ eiop->eio_enable(enp);
+}
+
+ void
+efx_intr_disable(
+ __in efx_nic_t *enp)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ efx_intr_ops_t *eiop = eip->ei_eiop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+ eiop->eio_disable(enp);
+}
+
+ void
+efx_intr_disable_unlocked(
+ __in efx_nic_t *enp)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ efx_intr_ops_t *eiop = eip->ei_eiop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+ eiop->eio_disable_unlocked(enp);
+}
+
+
+ __checkReturn int
+efx_intr_trigger(
+ __in efx_nic_t *enp,
+ __in unsigned int level)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ efx_intr_ops_t *eiop = eip->ei_eiop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+ return (eiop->eio_trigger(enp, level));
+}
+
+ void
+efx_intr_status_line(
+ __in efx_nic_t *enp,
+ __out boolean_t *fatalp,
+ __out uint32_t *qmaskp)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ efx_dword_t dword;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+ /* Ensure Huntington and Falcon/Siena ISR at same location */
+ EFX_STATIC_ASSERT(FR_BZ_INT_ISR0_REG_OFST ==
+ ER_DZ_BIU_INT_ISR_REG_OFST);
+
+ /*
+ * Read the queue mask and implicitly acknowledge the
+ * interrupt.
+ */
+ EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
+ *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
+
+ EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
+
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /* Huntington reports fatal errors via events */
+ *fatalp = B_FALSE;
+ return;
+ }
+#endif
+ if (*qmaskp & (1U << eip->ei_level))
+ *fatalp = falconsiena_intr_check_fatal(enp);
+ else
+ *fatalp = B_FALSE;
+}
+
+ void
+efx_intr_status_message(
+ __in efx_nic_t *enp,
+ __in unsigned int message,
+ __out boolean_t *fatalp)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /* Huntington reports fatal errors via events */
+ *fatalp = B_FALSE;
+ return;
+ }
+#endif
+ if (message == eip->ei_level)
+ *fatalp = falconsiena_intr_check_fatal(enp);
+ else
+ *fatalp = B_FALSE;
+}
+
+ void
+efx_intr_fatal(
+ __in efx_nic_t *enp)
+{
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /* Huntington reports fatal errors via events */
+ return;
+ }
+#endif
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+ falconsiena_intr_fatal(enp);
+#endif
+}
+
+
+/* ************************************************************************* */
+/* ************************************************************************* */
+/* ************************************************************************* */
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_intr_init(
+ __in efx_nic_t *enp,
+ __in efx_intr_type_t type,
+ __in efsys_mem_t *esmp)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ efx_oword_t oword;
/*
* bug17213 workaround.
@@ -85,23 +375,15 @@ efx_intr_init(
EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
}
- void
-efx_intr_enable(
+static void
+falconsiena_intr_enable(
__in efx_nic_t *enp)
{
efx_intr_t *eip = &(enp->en_intr);
efx_oword_t oword;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
@@ -109,15 +391,12 @@ efx_intr_enable(
EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
}
- void
-efx_intr_disable(
+static void
+falconsiena_intr_disable(
__in efx_nic_t *enp)
{
efx_oword_t oword;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
@@ -125,15 +404,12 @@ efx_intr_disable(
EFSYS_SPIN(10);
}
- void
-efx_intr_disable_unlocked(
+static void
+falconsiena_intr_disable_unlocked(
__in efx_nic_t *enp)
{
efx_oword_t oword;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
&oword, B_FALSE);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
@@ -141,8 +417,8 @@ efx_intr_disable_unlocked(
&oword, B_FALSE);
}
- __checkReturn int
-efx_intr_trigger(
+static __checkReturn int
+falconsiena_intr_trigger(
__in efx_nic_t *enp,
__in unsigned int level)
{
@@ -152,22 +428,19 @@ efx_intr_trigger(
uint32_t sel;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
/* bug16757: No event queues can be initialized */
EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
switch (enp->en_family) {
case EFX_FAMILY_FALCON:
- if (level > EFX_NINTR_FALCON) {
+ if (level >= EFX_NINTR_FALCON) {
rc = EINVAL;
goto fail1;
}
break;
case EFX_FAMILY_SIENA:
- if (level > EFX_NINTR_SIENA) {
+ if (level >= EFX_NINTR_SIENA) {
rc = EINVAL;
goto fail1;
}
@@ -213,7 +486,7 @@ fail1:
}
static __checkReturn boolean_t
-efx_intr_check_fatal(
+falconsiena_intr_check_fatal(
__in efx_nic_t *enp)
{
efx_intr_t *eip = &(enp->en_intr);
@@ -236,61 +509,14 @@ efx_intr_check_fatal(
return (B_FALSE);
}
- void
-efx_intr_status_line(
- __in efx_nic_t *enp,
- __out boolean_t *fatalp,
- __out uint32_t *qmaskp)
-{
- efx_intr_t *eip = &(enp->en_intr);
- efx_dword_t dword;
-
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
- /*
- * Read the queue mask and implicitly acknowledge the
- * interrupt.
- */
- EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
- *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
-
- EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
-
- if (*qmaskp & (1U << eip->ei_level))
- *fatalp = efx_intr_check_fatal(enp);
- else
- *fatalp = B_FALSE;
-}
-
- void
-efx_intr_status_message(
- __in efx_nic_t *enp,
- __in unsigned int message,
- __out boolean_t *fatalp)
-{
- efx_intr_t *eip = &(enp->en_intr);
-
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
- if (message == eip->ei_level)
- *fatalp = efx_intr_check_fatal(enp);
- else
- *fatalp = B_FALSE;
-}
-
- void
-efx_intr_fatal(
+static void
+falconsiena_intr_fatal(
__in efx_nic_t *enp)
{
#if EFSYS_OPT_DECODE_INTR_FATAL
efx_oword_t fatal;
efx_oword_t mem_per;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
EFX_ZERO_OWORD(mem_per);
@@ -339,19 +565,15 @@ efx_intr_fatal(
#endif
}
- void
-efx_intr_fini(
+static void
+falconsiena_intr_fini(
__in efx_nic_t *enp)
{
efx_oword_t oword;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
/* Clear the interrupt address register */
EFX_ZERO_OWORD(oword);
EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
-
- enp->en_mod_flags &= ~EFX_MOD_INTR;
}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_mac.c b/sys/dev/sfxge/common/efx_mac.c
index 3e9449ad70fb..a701797c80bb 100644
--- a/sys/dev/sfxge/common/efx_mac.c
+++ b/sys/dev/sfxge/common/efx_mac.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -39,74 +44,126 @@ __FBSDID("$FreeBSD$");
#include "falcon_xmac.h"
#endif
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_mac_multicast_list_set(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
#if EFSYS_OPT_MAC_FALCON_GMAC
-static efx_mac_ops_t __cs __efx_falcon_gmac_ops = {
- falcon_gmac_reset, /* emo_reset */
- falcon_mac_poll, /* emo_poll */
- falcon_mac_up, /* emo_up */
- falcon_gmac_reconfigure, /* emo_reconfigure */
+static efx_mac_ops_t __efx_falcon_gmac_ops = {
+ falcon_gmac_reset, /* emo_reset */
+ falcon_mac_poll, /* emo_poll */
+ falcon_mac_up, /* emo_up */
+ falcon_gmac_reconfigure, /* emo_addr_set */
+ falcon_gmac_reconfigure, /* emo_reconfigure */
+ falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
+ NULL, /* emo_filter_set_default_rxq */
+ NULL, /* emo_filter_default_rxq_clear */
#if EFSYS_OPT_LOOPBACK
- falcon_mac_loopback_set, /* emo_loopback_set */
+ falcon_mac_loopback_set, /* emo_loopback_set */
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_MAC_STATS
- falcon_mac_stats_upload, /* emo_stats_upload */
- NULL, /* emo_stats_periodic */
- falcon_gmac_stats_update /* emo_stats_update */
+ falcon_mac_stats_upload, /* emo_stats_upload */
+ NULL, /* emo_stats_periodic */
+ falcon_gmac_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MAC_STATS */
};
#endif /* EFSYS_OPT_MAC_FALCON_GMAC */
#if EFSYS_OPT_MAC_FALCON_XMAC
-static efx_mac_ops_t __cs __efx_falcon_xmac_ops = {
- falcon_xmac_reset, /* emo_reset */
- falcon_mac_poll, /* emo_poll */
- falcon_mac_up, /* emo_up */
- falcon_xmac_reconfigure, /* emo_reconfigure */
+static efx_mac_ops_t __efx_falcon_xmac_ops = {
+ falcon_xmac_reset, /* emo_reset */
+ falcon_mac_poll, /* emo_poll */
+ falcon_mac_up, /* emo_up */
+ falcon_xmac_reconfigure, /* emo_addr_set */
+ falcon_xmac_reconfigure, /* emo_reconfigure */
+ falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
+ NULL, /* emo_filter_set_default_rxq */
+ NULL, /* emo_filter_default_rxq_clear */
#if EFSYS_OPT_LOOPBACK
- falcon_mac_loopback_set, /* emo_loopback_set */
+ falcon_mac_loopback_set, /* emo_loopback_set */
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_MAC_STATS
- falcon_mac_stats_upload, /* emo_stats_upload */
- NULL, /* emo_stats_periodic */
- falcon_xmac_stats_update /* emo_stats_update */
+ falcon_mac_stats_upload, /* emo_stats_upload */
+ NULL, /* emo_stats_periodic */
+ falcon_xmac_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MAC_STATS */
};
#endif /* EFSYS_OPT_MAC_FALCON_XMAC */
#if EFSYS_OPT_SIENA
-static efx_mac_ops_t __cs __efx_siena_mac_ops = {
- NULL, /* emo_reset */
- siena_mac_poll, /* emo_poll */
- siena_mac_up, /* emo_up */
- siena_mac_reconfigure, /* emo_reconfigure */
+static efx_mac_ops_t __efx_siena_mac_ops = {
+ NULL, /* emo_reset */
+ siena_mac_poll, /* emo_poll */
+ siena_mac_up, /* emo_up */
+ siena_mac_reconfigure, /* emo_addr_set */
+ siena_mac_reconfigure, /* emo_reconfigure */
+ falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
+ NULL, /* emo_filter_set_default_rxq */
+ NULL, /* emo_filter_default_rxq_clear */
#if EFSYS_OPT_LOOPBACK
- siena_mac_loopback_set, /* emo_loopback_set */
+ siena_mac_loopback_set, /* emo_loopback_set */
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_MAC_STATS
- siena_mac_stats_upload, /* emo_stats_upload */
- siena_mac_stats_periodic, /* emo_stats_periodic */
- siena_mac_stats_update /* emo_stats_update */
+ efx_mcdi_mac_stats_upload, /* emo_stats_upload */
+ efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
+ siena_mac_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MAC_STATS */
};
#endif /* EFSYS_OPT_SIENA */
-static efx_mac_ops_t __cs * __cs __efx_mac_ops[] = {
+#if EFSYS_OPT_HUNTINGTON
+static efx_mac_ops_t __efx_hunt_mac_ops = {
+ NULL, /* emo_reset */
+ hunt_mac_poll, /* emo_poll */
+ hunt_mac_up, /* emo_up */
+ hunt_mac_addr_set, /* emo_addr_set */
+ hunt_mac_reconfigure, /* emo_reconfigure */
+ hunt_mac_multicast_list_set, /* emo_multicast_list_set */
+ hunt_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
+ hunt_mac_filter_default_rxq_clear,
+ /* emo_filter_default_rxq_clear */
+#if EFSYS_OPT_LOOPBACK
+ hunt_mac_loopback_set, /* emo_loopback_set */
+#endif /* EFSYS_OPT_LOOPBACK */
+#if EFSYS_OPT_MAC_STATS
+ efx_mcdi_mac_stats_upload, /* emo_stats_upload */
+ efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
+ hunt_mac_stats_update /* emo_stats_update */
+#endif /* EFSYS_OPT_MAC_STATS */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+static efx_mac_ops_t *__efx_mac_ops[] = {
+ /* [EFX_MAC_INVALID] */
NULL,
+ /* [EFX_MAC_FALCON_GMAC] */
#if EFSYS_OPT_MAC_FALCON_GMAC
&__efx_falcon_gmac_ops,
#else
NULL,
-#endif /* EFSYS_OPT_MAC_FALCON_GMAC */
+#endif
+ /* [EFX_MAC_FALCON_XMAC] */
#if EFSYS_OPT_MAC_FALCON_XMAC
&__efx_falcon_xmac_ops,
#else
NULL,
-#endif /* EFSYS_OPT_MAC_FALCON_XMAC */
+#endif
+ /* [EFX_MAC_SIENA] */
#if EFSYS_OPT_SIENA
&__efx_siena_mac_ops,
#else
NULL,
-#endif /* EFSYS_OPT_SIENA */
+#endif
+ /* [EFX_MAC_HUNTINGTON] */
+#if EFSYS_OPT_HUNTINGTON
+ &__efx_hunt_mac_ops,
+#else
+ NULL,
+#endif
};
__checkReturn int
@@ -167,7 +224,7 @@ efx_mac_addr_set(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- if (addr[0] & 0x01) {
+ if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
rc = EINVAL;
goto fail1;
}
@@ -180,7 +237,7 @@ efx_mac_addr_set(
EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
- if ((rc = emop->emo_reconfigure(enp)) != 0)
+ if ((rc = emop->emo_addr_set(enp)) != 0)
goto fail3;
return (0);
@@ -201,22 +258,30 @@ fail1:
__checkReturn int
efx_mac_filter_set(
__in efx_nic_t *enp,
- __in boolean_t unicst,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
__in boolean_t brdcst)
{
efx_port_t *epp = &(enp->en_port);
efx_mac_ops_t *emop = epp->ep_emop;
- boolean_t old_unicst;
+ boolean_t old_all_unicst;
+ boolean_t old_mulcst;
+ boolean_t old_all_mulcst;
boolean_t old_brdcst;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- old_unicst = unicst;
- old_brdcst = brdcst;
+ old_all_unicst = epp->ep_all_unicst;
+ old_mulcst = epp->ep_mulcst;
+ old_all_mulcst = epp->ep_all_mulcst;
+ old_brdcst = epp->ep_brdcst;
- epp->ep_unicst = unicst;
+ epp->ep_all_unicst = all_unicst;
+ epp->ep_mulcst = mulcst;
+ epp->ep_all_mulcst = all_mulcst;
epp->ep_brdcst = brdcst;
if ((rc = emop->emo_reconfigure(enp)) != 0)
@@ -227,7 +292,9 @@ efx_mac_filter_set(
fail1:
EFSYS_PROBE1(fail1, int, rc);
- epp->ep_unicst = old_unicst;
+ epp->ep_all_unicst = old_all_unicst;
+ epp->ep_mulcst = old_mulcst;
+ epp->ep_all_mulcst = old_all_mulcst;
epp->ep_brdcst = old_brdcst;
return (rc);
@@ -318,45 +385,45 @@ efx_mac_fcntl_set(
}
/*
- * Ignore a request to set flow control autonegotiation
+ * Ignore a request to set flow control auto-negotiation
* if the PHY doesn't support it.
*/
if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
autoneg = B_FALSE;
old_fcntl = epp->ep_fcntl;
- old_autoneg = autoneg;
+ old_autoneg = epp->ep_fcntl_autoneg;
old_adv_cap = epp->ep_adv_cap_mask;
epp->ep_fcntl = fcntl;
epp->ep_fcntl_autoneg = autoneg;
/*
- * If the PHY supports autonegotiation, then encode the flow control
- * settings in the advertised capabilities, and restart AN. Otherwise,
- * just push the new settings directly to the MAC.
+ * Always encode the flow control settings in the advertised
+ * capabilities even if we are not trying to auto-negotiate
+ * them and reconfigure both the PHY and the MAC.
*/
- if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
- if (fcntl & EFX_FCNTL_RESPOND)
- epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
- 1 << EFX_PHY_CAP_ASYM);
- else
- epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
- 1 << EFX_PHY_CAP_ASYM);
+ if (fcntl & EFX_FCNTL_RESPOND)
+ epp->ep_adv_cap_mask |= (1 << EFX_PHY_CAP_PAUSE |
+ 1 << EFX_PHY_CAP_ASYM);
+ else
+ epp->ep_adv_cap_mask &= ~(1 << EFX_PHY_CAP_PAUSE |
+ 1 << EFX_PHY_CAP_ASYM);
- if (fcntl & EFX_FCNTL_GENERATE)
- epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
+ if (fcntl & EFX_FCNTL_GENERATE)
+ epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
- if ((rc = epop->epo_reconfigure(enp)) != 0)
- goto fail2;
+ if ((rc = epop->epo_reconfigure(enp)) != 0)
+ goto fail2;
- } else {
- if ((rc = emop->emo_reconfigure(enp)) != 0)
- goto fail2;
- }
+ if ((rc = emop->emo_reconfigure(enp)) != 0)
+ goto fail3;
return (0);
+fail3:
+ EFSYS_PROBE(fail3);
+
fail2:
EFSYS_PROBE(fail2);
@@ -377,29 +444,30 @@ efx_mac_fcntl_get(
__out unsigned int *fcntl_linkp)
{
efx_port_t *epp = &(enp->en_port);
- unsigned int wanted;
+ unsigned int wanted = 0;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
/*
- * If the PHY supports auto negotiation, then the requested flow
- * control settings are encoded in the advertised capabilities.
+ * Decode the requested flow control settings from the PHY
+ * advertised capabilities.
*/
- if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
- wanted = 0;
-
- if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
- wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
- if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
- wanted ^= EFX_FCNTL_GENERATE;
- } else
- wanted = epp->ep_fcntl;
+ if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
+ wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
+ if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
+ wanted ^= EFX_FCNTL_GENERATE;
*fcntl_linkp = epp->ep_fcntl;
*fcntl_wantedp = wanted;
}
+/*
+ * FIXME: efx_mac_hash_set() should be deleted once all its callers have been
+ * updated to use efx_mac_multicast_list_set().
+ * Then efx_port_t.ep_multicst_hash could be made Falcon/Siena specific as
+ * well.
+ */
__checkReturn int
efx_mac_hash_set(
__in efx_nic_t *enp,
@@ -443,12 +511,130 @@ fail1:
return (rc);
}
+ __checkReturn int
+efx_mac_multicast_list_set(
+ __in efx_nic_t *enp,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mac_ops_t *emop = epp->ep_emop;
+ uint8_t *old_mulcst_addr_list = NULL;
+ uint32_t old_mulcst_addr_count;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+ if (count > EFX_MAC_MULTICAST_LIST_MAX) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ old_mulcst_addr_count = epp->ep_mulcst_addr_count;
+ if (old_mulcst_addr_count > 0) {
+ /* Allocate memory to store old list (instead of using stack) */
+ EFSYS_KMEM_ALLOC(enp->en_esip,
+ old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
+ old_mulcst_addr_list);
+ if (old_mulcst_addr_list == NULL) {
+ rc = ENOMEM;
+ goto fail2;
+ }
+
+ /* Save the old list in case we need to rollback */
+ memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
+ old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
+ }
+
+ /* Store the new list */
+ memcpy(epp->ep_mulcst_addr_list, addrs,
+ count * EFX_MAC_ADDR_LEN);
+ epp->ep_mulcst_addr_count = count;
+
+ if ((rc = emop->emo_multicast_list_set(enp)) != 0)
+ goto fail3;
+
+ if (old_mulcst_addr_count > 0) {
+ EFSYS_KMEM_FREE(enp->en_esip,
+ old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
+ old_mulcst_addr_list);
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+
+ /* Restore original list on failure */
+ epp->ep_mulcst_addr_count = old_mulcst_addr_count;
+ if (old_mulcst_addr_count > 0) {
+ memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
+ old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
+
+ EFSYS_KMEM_FREE(enp->en_esip,
+ old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
+ old_mulcst_addr_list);
+ }
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
+
+ __checkReturn int
+efx_mac_filter_default_rxq_set(
+ __in efx_nic_t *enp,
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mac_ops_t *emop = epp->ep_emop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+ if (emop->emo_filter_default_rxq_set != NULL) {
+ rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
+ if (rc != 0)
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_mac_filter_default_rxq_clear(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mac_ops_t *emop = epp->ep_emop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+ if (emop->emo_filter_default_rxq_clear != NULL)
+ emop->emo_filter_default_rxq_clear(enp);
+}
+
+
#if EFSYS_OPT_MAC_STATS
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED EfxMacStatNamesBlock adf707adba80813e */
-static const char __cs * __cs __efx_mac_stat_name[] = {
+/* START MKCONFIG GENERATED EfxMacStatNamesBlock 054d43a31d2d7a45 */
+static const char *__efx_mac_stat_name[] = {
"rx_octets",
"rx_pkts",
"rx_unicst_pkts",
@@ -500,10 +686,40 @@ static const char __cs * __cs __efx_mac_stat_name[] = {
"tx_late_col_pkts",
"tx_def_pkts",
"tx_ex_def_pkts",
+ "pm_trunc_bb_overflow",
+ "pm_discard_bb_overflow",
+ "pm_trunc_vfifo_full",
+ "pm_discard_vfifo_full",
+ "pm_trunc_qbb",
+ "pm_discard_qbb",
+ "pm_discard_mapping",
+ "rxdp_q_disabled_pkts",
+ "rxdp_di_dropped_pkts",
+ "rxdp_streaming_pkts",
+ "rxdp_hlb_fetch",
+ "rxdp_hlb_wait",
+ "vadapter_rx_unicast_packets",
+ "vadapter_rx_unicast_bytes",
+ "vadapter_rx_multicast_packets",
+ "vadapter_rx_multicast_bytes",
+ "vadapter_rx_broadcast_packets",
+ "vadapter_rx_broadcast_bytes",
+ "vadapter_rx_bad_packets",
+ "vadapter_rx_bad_bytes",
+ "vadapter_rx_overflow",
+ "vadapter_tx_unicast_packets",
+ "vadapter_tx_unicast_bytes",
+ "vadapter_tx_multicast_packets",
+ "vadapter_tx_multicast_bytes",
+ "vadapter_tx_broadcast_packets",
+ "vadapter_tx_broadcast_bytes",
+ "vadapter_tx_bad_packets",
+ "vadapter_tx_bad_bytes",
+ "vadapter_tx_overflow",
};
/* END MKCONFIG GENERATED EfxMacStatNamesBlock */
- __checkReturn const char __cs *
+ __checkReturn const char *
efx_mac_stat_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -515,7 +731,7 @@ efx_mac_stat_name(
return (__efx_mac_stat_name[id]);
}
-#endif /* EFSYS_OPT_STAT_NAME */
+#endif /* EFSYS_OPT_NAMES */
__checkReturn int
efx_mac_stats_upload(
@@ -588,7 +804,7 @@ efx_mac_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
__inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
- __in uint32_t *generationp)
+ __out_opt uint32_t *generationp)
{
efx_port_t *epp = &(enp->en_port);
efx_mac_ops_t *emop = epp->ep_emop;
@@ -616,6 +832,13 @@ efx_mac_select(
efx_mac_ops_t *emop;
int rc = EINVAL;
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ type = EFX_MAC_HUNTINGTON;
+ goto chosen;
+ }
+#endif
+
#if EFSYS_OPT_SIENA
if (enp->en_family == EFX_FAMILY_SIENA) {
type = EFX_MAC_SIENA;
@@ -685,3 +908,71 @@ fail1:
return (rc);
}
+
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+/* Compute the multicast hash as used on Falcon and Siena. */
+static void
+falconsiena_mac_multicast_hash_compute(
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count,
+ __out efx_oword_t *hash_low,
+ __out efx_oword_t *hash_high)
+{
+ uint32_t crc, index;
+ int i;
+
+ EFSYS_ASSERT(hash_low != NULL);
+ EFSYS_ASSERT(hash_high != NULL);
+
+ EFX_ZERO_OWORD(*hash_low);
+ EFX_ZERO_OWORD(*hash_high);
+
+ for (i = 0; i < count; i++) {
+ /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
+ crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
+ index = crc % EFX_MAC_HASH_BITS;
+ if (index < 128) {
+ EFX_SET_OWORD_BIT(*hash_low, index);
+ } else {
+ EFX_SET_OWORD_BIT(*hash_high, index - 128);
+ }
+
+ addrs += EFX_MAC_ADDR_LEN;
+ }
+}
+
+static __checkReturn int
+falconsiena_mac_multicast_list_set(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mac_ops_t *emop = epp->ep_emop;
+ efx_oword_t old_hash[2];
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+ memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
+
+ falconsiena_mac_multicast_hash_compute(epp->ep_mulcst_addr_list,
+ epp->ep_mulcst_addr_count,
+ &epp->ep_multicst_hash[0],
+ &epp->ep_multicst_hash[1]);
+
+ if ((rc = emop->emo_reconfigure(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c
index f389d57c7acc..e1c4b456dd59 100644
--- a/sys/dev/sfxge/common/efx_mcdi.c
+++ b/sys/dev/sfxge/common/efx_mcdi.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2008-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2008-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -35,12 +40,144 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_MCDI
-/*
- * A reboot/assertion causes the MCDI status word to be set after the
- * command word is set or a REBOOT event is sent. If we notice a reboot
- * via these mechanisms then wait 10ms for the status word to be set.
- */
-#define MCDI_STATUS_SLEEP_US 10000
+
+#if EFSYS_OPT_SIENA
+
+static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
+ siena_mcdi_init, /* emco_init */
+ siena_mcdi_request_copyin, /* emco_request_copyin */
+ siena_mcdi_request_poll, /* emco_request_poll */
+ siena_mcdi_request_copyout, /* emco_request_copyout */
+ siena_mcdi_poll_reboot, /* emco_poll_reboot */
+ siena_mcdi_fini, /* emco_fini */
+ siena_mcdi_fw_update_supported, /* emco_fw_update_supported */
+ siena_mcdi_macaddr_change_supported,
+ /* emco_macaddr_change_supported */
+};
+
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+
+static efx_mcdi_ops_t __efx_mcdi_hunt_ops = {
+ hunt_mcdi_init, /* emco_init */
+ hunt_mcdi_request_copyin, /* emco_request_copyin */
+ hunt_mcdi_request_poll, /* emco_request_poll */
+ hunt_mcdi_request_copyout, /* emco_request_copyout */
+ hunt_mcdi_poll_reboot, /* emco_poll_reboot */
+ hunt_mcdi_fini, /* emco_fini */
+ hunt_mcdi_fw_update_supported, /* emco_fw_update_supported */
+ hunt_mcdi_macaddr_change_supported,
+ /* emco_macaddr_change_supported */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+
+
+ __checkReturn int
+efx_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *emtp)
+{
+ efx_mcdi_ops_t *emcop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
+
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ emcop = NULL;
+ emtp = NULL;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ emcop = (efx_mcdi_ops_t *)&__efx_mcdi_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ emcop = (efx_mcdi_ops_t *)&__efx_mcdi_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if (enp->en_features & EFX_FEATURE_MCDI_DMA) {
+ /* MCDI requires a DMA buffer in host memory */
+ if ((emtp == NULL) || (emtp->emt_dma_mem) == NULL) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ }
+ enp->en_mcdi.em_emtp = emtp;
+
+ if (emcop != NULL && emcop->emco_init != NULL) {
+ if ((rc = emcop->emco_init(enp, emtp)) != 0)
+ goto fail3;
+ }
+
+ enp->en_mcdi.em_emcop = emcop;
+ enp->en_mod_flags |= EFX_MOD_MCDI;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ enp->en_mcdi.em_emcop = NULL;
+ enp->en_mcdi.em_emtp = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_MCDI;
+
+ return (rc);
+}
+
+ void
+efx_mcdi_fini(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, ==, EFX_MOD_MCDI);
+
+ if (emcop != NULL && emcop->emco_fini != NULL)
+ emcop->emco_fini(enp);
+
+ emip->emi_port = 0;
+ emip->emi_aborted = 0;
+
+ enp->en_mcdi.em_emcop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_MCDI;
+}
+
+ void
+efx_mcdi_new_epoch(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ int state;
+
+ /* Start a new epoch (allow fresh MCDI requests to succeed) */
+ EFSYS_LOCK(enp->en_eslp, state);
+ emip->emi_new_epoch = B_TRUE;
+ EFSYS_UNLOCK(enp->en_eslp, state);
+}
+
void
efx_mcdi_request_start(
@@ -48,32 +185,18 @@ efx_mcdi_request_start(
__in efx_mcdi_req_t *emrp,
__in boolean_t ev_cpl)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_dword_t dword;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
unsigned int seq;
- unsigned int xflags;
- unsigned int pdur;
- unsigned int dbr;
- unsigned int pos;
+ boolean_t new_epoch;
int state;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- switch (emip->emi_port) {
- case 1:
- pdur = MC_SMEM_P0_PDU_OFST >> 2;
- dbr = MC_SMEM_P0_DOORBELL_OFST >> 2;
- break;
- case 2:
- pdur = MC_SMEM_P1_PDU_OFST >> 2;
- dbr = MC_SMEM_P1_DOORBELL_OFST >> 2;
- break;
- default:
- EFSYS_ASSERT(0);
- pdur = dbr = 0;
- };
+ if (emcop == NULL || emcop->emco_request_copyin == NULL)
+ return;
/*
* efx_mcdi_request_start() is naturally serialised against both
@@ -92,68 +215,85 @@ efx_mcdi_request_start(
emip->emi_pending_req = emrp;
emip->emi_ev_cpl = ev_cpl;
emip->emi_poll_cnt = 0;
- seq = emip->emi_seq++ & 0xf;
+ seq = emip->emi_seq++ & EFX_MASK32(MCDI_HEADER_SEQ);
+ new_epoch = emip->emi_new_epoch;
EFSYS_UNLOCK(enp->en_eslp, state);
- xflags = 0;
- if (ev_cpl)
- xflags |= MCDI_HEADER_XFLAGS_EVREQ;
+ emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
+}
+
+ __checkReturn boolean_t
+efx_mcdi_request_poll(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ boolean_t completed;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
+ EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- /* Construct the header in shared memory */
- EFX_POPULATE_DWORD_6(dword,
- MCDI_HEADER_CODE, emrp->emr_cmd,
- MCDI_HEADER_RESYNC, 1,
- MCDI_HEADER_DATALEN, emrp->emr_in_length,
- MCDI_HEADER_SEQ, seq,
- MCDI_HEADER_RESPONSE, 0,
- MCDI_HEADER_XFLAGS, xflags);
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE);
+ completed = B_FALSE;
- for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
- memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
- MIN(sizeof (dword), emrp->emr_in_length - pos));
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,
- pdur + 1 + (pos >> 2), &dword, B_FALSE);
- }
+ if (emcop != NULL && emcop->emco_request_poll != NULL)
+ completed = emcop->emco_request_poll(enp);
- /* Ring the doorbell */
- EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
+ return (completed);
}
-static void
-efx_mcdi_request_copyout(
- __in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp)
-{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- unsigned int pos;
- unsigned int pdur;
- efx_dword_t data;
-
- pdur = (emip->emi_port == 1)
- ? MC_SMEM_P0_PDU_OFST >> 2
- : MC_SMEM_P1_PDU_OFST >> 2;
-
- /* Copy payload out if caller supplied buffer */
- if (emrp->emr_out_buf != NULL) {
- size_t bytes = MIN(emrp->emr_out_length_used,
- emrp->emr_out_length);
- for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) {
- EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
- pdur + 1 + (pos >> 2), &data, B_FALSE);
- memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
- MIN(sizeof (data), bytes - pos));
- }
+ __checkReturn boolean_t
+efx_mcdi_request_abort(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_req_t *emrp;
+ boolean_t aborted;
+ int state;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
+ EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
+
+ /*
+ * efx_mcdi_ev_* may have already completed this event, and be
+ * spinning/blocked on the upper layer lock. So it *is* legitimate
+ * to for emi_pending_req to be NULL. If there is a pending event
+ * completed request, then provide a "credit" to allow
+ * efx_mcdi_ev_cpl() to accept a single spurious completion.
+ */
+ EFSYS_LOCK(enp->en_eslp, state);
+ emrp = emip->emi_pending_req;
+ aborted = (emrp != NULL);
+ if (aborted) {
+ emip->emi_pending_req = NULL;
+
+ /* Error the request */
+ emrp->emr_out_length_used = 0;
+ emrp->emr_rc = ETIMEDOUT;
+
+ /* Provide a credit for seqno/emr_pending_req mismatches */
+ if (emip->emi_ev_cpl)
+ ++emip->emi_aborted;
+
+ /*
+ * The upper layer has called us, so we don't
+ * need to complete the request.
+ */
}
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ return (aborted);
}
-static int
+ __checkReturn int
efx_mcdi_request_errcode(
__in unsigned int err)
{
switch (err) {
+ /* MCDI v1 */
+ case MC_CMD_ERR_EPERM:
+ return (EACCES);
case MC_CMD_ERR_ENOENT:
return (ENOENT);
case MC_CMD_ERR_EINTR:
@@ -170,26 +310,55 @@ efx_mcdi_request_errcode(
return (ENOTSUP);
case MC_CMD_ERR_ETIME:
return (ETIMEDOUT);
-#ifdef WITH_MCDI_V2
+ case MC_CMD_ERR_ENOTSUP:
+ return (ENOTSUP);
+ case MC_CMD_ERR_EALREADY:
+ return (EALREADY);
+
+ /* MCDI v2 */
+#ifdef MC_CMD_ERR_EAGAIN
case MC_CMD_ERR_EAGAIN:
return (EAGAIN);
+#endif
+#ifdef MC_CMD_ERR_ENOSPC
case MC_CMD_ERR_ENOSPC:
return (ENOSPC);
#endif
+
+ case MC_CMD_ERR_ALLOC_FAIL:
+ return (ENOMEM);
+ case MC_CMD_ERR_NO_VADAPTOR:
+ return (ENOENT);
+ case MC_CMD_ERR_NO_EVB_PORT:
+ return (ENOENT);
+ case MC_CMD_ERR_NO_VSWITCH:
+ return (ENODEV);
+ case MC_CMD_ERR_VLAN_LIMIT:
+ return (EINVAL);
+ case MC_CMD_ERR_BAD_PCI_FUNC:
+ return (ENODEV);
+ case MC_CMD_ERR_BAD_VLAN_MODE:
+ return (EINVAL);
+ case MC_CMD_ERR_BAD_VSWITCH_TYPE:
+ return (EINVAL);
+ case MC_CMD_ERR_BAD_VPORT_TYPE:
+ return (EINVAL);
+ case MC_CMD_ERR_MAC_EXIST:
+ return (EEXIST);
+
default:
EFSYS_PROBE1(mc_pcol_error, int, err);
return (EIO);
}
}
-static void
+ void
efx_mcdi_raise_exception(
__in efx_nic_t *enp,
__in_opt efx_mcdi_req_t *emrp,
__in int rc)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- const efx_mcdi_transport_t *emtp = emip->emi_mtp;
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
efx_mcdi_exception_t exception;
/* Reboot or Assertion failure only */
@@ -213,167 +382,37 @@ static int
efx_mcdi_poll_reboot(
__in efx_nic_t *enp)
{
-#ifndef EFX_GRACEFUL_MC_REBOOT
- /*
- * This function is not being used properly.
- * Until its callers are fixed, it should always return 0.
- */
- _NOTE(ARGUNUSED(enp))
- return (0);
-#else
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- unsigned int rebootr;
- efx_dword_t dword;
- uint32_t value;
-
- EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
- rebootr = ((emip->emi_port == 1)
- ? MC_SMEM_P0_STATUS_OFST >> 2
- : MC_SMEM_P1_STATUS_OFST >> 2);
-
- EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);
- value = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
-
- if (value == 0)
- return (0);
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
- EFX_ZERO_DWORD(dword);
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);
-
- if (value == MC_STATUS_DWORD_ASSERT)
- return (EINTR);
- else
- return (EIO);
-#endif
+ return (emcop->emco_poll_reboot(enp));
}
- __checkReturn boolean_t
-efx_mcdi_request_poll(
- __in efx_nic_t *enp)
+
+ void
+efx_mcdi_execute(
+ __in efx_nic_t *enp,
+ __inout efx_mcdi_req_t *emrp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_mcdi_req_t *emrp;
- efx_dword_t dword;
- unsigned int pdur;
- unsigned int seq;
- unsigned int length;
- int state;
- int rc;
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- /* Serialise against post-watchdog efx_mcdi_ev* */
- EFSYS_LOCK(enp->en_eslp, state);
-
- EFSYS_ASSERT(emip->emi_pending_req != NULL);
- EFSYS_ASSERT(!emip->emi_ev_cpl);
- emrp = emip->emi_pending_req;
-
- /* Check for reboot atomically w.r.t efx_mcdi_request_start */
- if (emip->emi_poll_cnt++ == 0) {
- if ((rc = efx_mcdi_poll_reboot(enp)) != 0) {
- emip->emi_pending_req = NULL;
- EFSYS_UNLOCK(enp->en_eslp, state);
-
- goto fail1;
- }
- }
-
- EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
- pdur = (emip->emi_port == 1)
- ? MC_SMEM_P0_PDU_OFST >> 2
- : MC_SMEM_P1_PDU_OFST >> 2;
-
- /* Read the command header */
- EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_FALSE);
- if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (B_FALSE);
- }
-
- /* Request complete */
- emip->emi_pending_req = NULL;
- seq = (emip->emi_seq - 1) & 0xf;
-
- /* Check for synchronous reboot */
- if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 &&
- EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN) == 0) {
- /* Consume status word */
- EFSYS_SPIN(MCDI_STATUS_SLEEP_US);
- efx_mcdi_poll_reboot(enp);
- EFSYS_UNLOCK(enp->en_eslp, state);
- rc = EIO;
- goto fail2;
- }
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-
- /* Check that the returned data is consistent */
- if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) != emrp->emr_cmd ||
- EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
- /* Response is for a different request */
- rc = EIO;
- goto fail3;
- }
-
- length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
- if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
- efx_dword_t errdword;
- int errcode;
-
- EFSYS_ASSERT3U(length, ==, 4);
- EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
- pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2),
- &errdword, B_FALSE);
- errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
- rc = efx_mcdi_request_errcode(errcode);
- EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd, int, errcode);
- goto fail4;
-
- } else {
- emrp->emr_out_length_used = length;
- emrp->emr_rc = 0;
- efx_mcdi_request_copyout(enp, emrp);
- }
-
- goto out;
-
-fail4:
- EFSYS_PROBE(fail4);
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- /* Fill out error state */
- emrp->emr_rc = rc;
- emrp->emr_out_length_used = 0;
-
- /* Reboot/Assertion */
- if (rc == EIO || rc == EINTR)
- efx_mcdi_raise_exception(enp, emrp, rc);
-
-out:
- return (B_TRUE);
+ emrp->emr_quiet = B_FALSE;
+ emtp->emt_execute(emtp->emt_context, emrp);
}
void
-efx_mcdi_execute(
+efx_mcdi_execute_quiet(
__in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp)
+ __inout efx_mcdi_req_t *emrp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- const efx_mcdi_transport_t *emtp = emip->emi_mtp;
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
+ emrp->emr_quiet = B_TRUE;
emtp->emt_execute(emtp->emt_context, emrp);
}
@@ -384,13 +423,13 @@ efx_mcdi_ev_cpl(
__in unsigned int outlen,
__in int errcode)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- const efx_mcdi_transport_t *emtp = emip->emi_mtp;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
efx_mcdi_req_t *emrp;
int state;
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
/*
@@ -399,7 +438,7 @@ efx_mcdi_ev_cpl(
*/
EFSYS_LOCK(enp->en_eslp, state);
if (emip->emi_pending_req == NULL || !emip->emi_ev_cpl ||
- (seq != ((emip->emi_seq - 1) & 0xf))) {
+ (seq != ((emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ)))) {
EFSYS_ASSERT(emip->emi_aborted > 0);
if (emip->emi_aborted > 0)
--emip->emi_aborted;
@@ -416,14 +455,17 @@ efx_mcdi_ev_cpl(
* if the user supplied an output buffer.
*/
if (errcode != 0) {
- EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
- int, errcode);
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
+ int, errcode);
+ }
emrp->emr_out_length_used = 0;
emrp->emr_rc = efx_mcdi_request_errcode(errcode);
} else {
emrp->emr_out_length_used = outlen;
emrp->emr_rc = 0;
- efx_mcdi_request_copyout(enp, emrp);
+
+ emcop->emco_request_copyout(enp, emrp);
}
emtp->emt_ev_cpl(emtp->emt_context);
@@ -434,8 +476,8 @@ efx_mcdi_ev_death(
__in efx_nic_t *enp,
__in int rc)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- const efx_mcdi_transport_t *emtp = emip->emi_mtp;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
efx_mcdi_req_t *emrp = NULL;
boolean_t ev_cpl;
int state;
@@ -469,8 +511,9 @@ efx_mcdi_ev_death(
* status word before dropping the lock.
*/
if (rc == EIO || rc == EINTR) {
- EFSYS_SPIN(MCDI_STATUS_SLEEP_US);
+ EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
(void) efx_mcdi_poll_reboot(enp);
+ emip->emi_new_epoch = B_TRUE;
}
EFSYS_UNLOCK(enp->en_eslp, state);
@@ -488,23 +531,24 @@ efx_mcdi_version(
__out_opt uint32_t *buildp,
__out_opt efx_mcdi_boot_t *statusp)
{
- uint8_t outbuf[MAX(MC_CMD_GET_VERSION_OUT_LEN,
- MC_CMD_GET_BOOT_STATUS_OUT_LEN)];
efx_mcdi_req_t req;
+ uint8_t payload[MAX(MAX(MC_CMD_GET_VERSION_IN_LEN,
+ MC_CMD_GET_VERSION_OUT_LEN),
+ MAX(MC_CMD_GET_BOOT_STATUS_IN_LEN,
+ MC_CMD_GET_BOOT_STATUS_OUT_LEN))];
efx_word_t *ver_words;
uint16_t version[4];
uint32_t build;
efx_mcdi_boot_t status;
int rc;
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- EFX_STATIC_ASSERT(MC_CMD_GET_VERSION_IN_LEN == 0);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_VERSION;
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_VERSION_IN_LEN;
+ req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_GET_VERSION_OUT_LEN;
efx_mcdi_execute(enp, &req);
@@ -536,19 +580,27 @@ efx_mcdi_version(
version:
/* The bootrom doesn't understand BOOT_STATUS */
- if (build == MC_CMD_GET_VERSION_OUT_FIRMWARE_SIENA_BOOTROM) {
+ if (MC_FW_VERSION_IS_BOOTLOADER(build)) {
status = EFX_MCDI_BOOT_ROM;
goto out;
}
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_BOOT_STATUS;
- EFX_STATIC_ASSERT(MC_CMD_GET_BOOT_STATUS_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_BOOT_STATUS_IN_LEN;
+ req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_GET_BOOT_STATUS_OUT_LEN;
- efx_mcdi_execute(enp, &req);
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc == EACCES) {
+ /* Unprivileged functions cannot access BOOT_STATUS */
+ status = EFX_MCDI_BOOT_PRIMARY;
+ version[0] = version[1] = version[2] = version[3] = 0;
+ build = 0;
+ goto out;
+ }
if (req.emr_rc != 0) {
rc = req.emr_rc;
@@ -588,86 +640,624 @@ fail1:
return (rc);
}
- __checkReturn int
-efx_mcdi_init(
+static __checkReturn int
+efx_mcdi_do_reboot(
__in efx_nic_t *enp,
- __in const efx_mcdi_transport_t *mtp)
+ __in boolean_t after_assertion)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_oword_t oword;
- unsigned int portnum;
+ uint8_t payload[MAX(MC_CMD_REBOOT_IN_LEN, MC_CMD_REBOOT_OUT_LEN)];
+ efx_mcdi_req_t req;
int rc;
- EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
- enp->en_mod_flags |= EFX_MOD_MCDI;
+ /*
+ * We could require the caller to have caused en_mod_flags=0 to
+ * call this function. This doesn't help the other port though,
+ * who's about to get the MC ripped out from underneath them.
+ * Since they have to cope with the subsequent fallout of MCDI
+ * failures, we should as well.
+ */
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- if (enp->en_family == EFX_FAMILY_FALCON)
- return (0);
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_REBOOT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_REBOOT_OUT_LEN;
- emip->emi_mtp = mtp;
+ MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS,
+ (after_assertion ? MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION : 0));
- /* Determine the port number to use for MCDI */
- EFX_BAR_READO(enp, FR_AZ_CS_DEBUG_REG, &oword);
- portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);
+ efx_mcdi_execute_quiet(enp, &req);
- if (portnum == 0) {
- /* Presumably booted from ROM; only MCDI port 1 will work */
- emip->emi_port = 1;
- } else if (portnum <= 2) {
- emip->emi_port = portnum;
- } else {
- rc = EINVAL;
+ if (req.emr_rc == EACCES) {
+ /* Unprivileged functions cannot reboot the MC. */
+ goto out;
+ }
+
+ /* A successful reboot request returns EIO. */
+ if (req.emr_rc != 0 && req.emr_rc != EIO) {
+ rc = req.emr_rc;
goto fail1;
}
+out:
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_reboot(
+ __in efx_nic_t *enp)
+{
+ return (efx_mcdi_do_reboot(enp, B_FALSE));
+}
+
+ __checkReturn int
+efx_mcdi_exit_assertion_handler(
+ __in efx_nic_t *enp)
+{
+ return (efx_mcdi_do_reboot(enp, B_TRUE));
+}
+
+ __checkReturn int
+efx_mcdi_read_assertion(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_ASSERTS_IN_LEN,
+ MC_CMD_GET_ASSERTS_OUT_LEN)];
+ const char *reason;
+ unsigned int flags;
+ unsigned int index;
+ unsigned int ofst;
+ int retry;
+ int rc;
+
/*
- * Wipe the atomic reboot status so subsequent MCDI requests succeed.
- * BOOT_STATUS is preserved so eno_nic_probe() can boot out of the
- * assertion handler.
+ * Before we attempt to chat to the MC, we should verify that the MC
+ * isn't in it's assertion handler, either due to a previous reboot,
+ * or because we're reinitializing due to an eec_exception().
+ *
+ * Use GET_ASSERTS to read any assertion state that may be present.
+ * Retry this command twice. Once because a boot-time assertion failure
+ * might cause the 1st MCDI request to fail. And once again because
+ * we might race with efx_mcdi_exit_assertion_handler() running on
+ * partner port(s) on the same NIC.
*/
- (void) efx_mcdi_poll_reboot(enp);
+ retry = 2;
+ do {
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_ASSERTS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_ASSERTS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_ASSERTS_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, GET_ASSERTS_IN_CLEAR, 1);
+ efx_mcdi_execute_quiet(enp, &req);
+
+ } while ((req.emr_rc == EINTR || req.emr_rc == EIO) && retry-- > 0);
+
+ if (req.emr_rc != 0) {
+ if (req.emr_rc == EACCES) {
+ /* Unprivileged functions cannot clear assertions. */
+ goto out;
+ }
+ rc = req.emr_rc;
+ goto fail1;
+ }
+ if (req.emr_out_length_used < MC_CMD_GET_ASSERTS_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ /* Print out any assertion state recorded */
+ flags = MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_GLOBAL_FLAGS);
+ if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
+ return (0);
+
+ reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
+ ? "system-level assertion"
+ : (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
+ ? "thread-level assertion"
+ : (flags == MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED)
+ ? "watchdog reset"
+ : (flags == MC_CMD_GET_ASSERTS_FLAGS_ADDR_TRAP)
+ ? "illegal address trap"
+ : "unknown assertion";
+ EFSYS_PROBE3(mcpu_assertion,
+ const char *, reason, unsigned int,
+ MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_SAVED_PC_OFFS),
+ unsigned int,
+ MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_THREAD_OFFS));
+
+ /* Print out the registers (r1 ... r31) */
+ ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
+ for (index = 1;
+ index < 1 + MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM;
+ index++) {
+ EFSYS_PROBE2(mcpu_register, unsigned int, index, unsigned int,
+ EFX_DWORD_FIELD(*MCDI_OUT(req, efx_dword_t, ofst),
+ EFX_DWORD_0));
+ ofst += sizeof (efx_dword_t);
+ }
+ EFSYS_ASSERT(ofst <= MC_CMD_GET_ASSERTS_OUT_LEN);
+
+out:
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
- enp->en_mod_flags &= ~EFX_MOD_MCDI;
-
return (rc);
}
+/*
+ * Internal routines for for specific MCDI requests.
+ */
+
__checkReturn int
-efx_mcdi_reboot(
- __in efx_nic_t *enp)
+efx_mcdi_drv_attach(
+ __in efx_nic_t *enp,
+ __in boolean_t attach)
{
- uint8_t payload[MC_CMD_REBOOT_IN_LEN];
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_DRV_ATTACH_IN_LEN,
+ MC_CMD_DRV_ATTACH_EXT_OUT_LEN)];
+ uint32_t flags;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_DRV_ATTACH;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_DRV_ATTACH_EXT_OUT_LEN;
+
/*
- * We could require the caller to have caused en_mod_flags=0 to
- * call this function. This doesn't help the other port though,
- * who's about to get the MC ripped out from underneath them.
- * Since they have to cope with the subsequent fallout of MCDI
- * failures, we should as well.
+ * Use DONT_CARE for the datapath firmware type to ensure that the
+ * driver can attach to an unprivileged function. The datapath firmware
+ * type to use is controlled by the 'sfboot' utility.
*/
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_NEW_STATE, attach ? 1 : 0);
+ MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_UPDATE, 1);
+ MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_FIRMWARE_ID, MC_CMD_FW_DONT_CARE);
- req.emr_cmd = MC_CMD_REBOOT;
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (attach == B_FALSE) {
+ flags = 0;
+ } else if (enp->en_family == EFX_FAMILY_SIENA) {
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+
+ /* Create synthetic privileges for Siena functions */
+ flags = EFX_NIC_FUNC_LINKCTRL | EFX_NIC_FUNC_TRUSTED;
+ if (emip->emi_port == 1)
+ flags |= EFX_NIC_FUNC_PRIMARY;
+ } else {
+ EFX_STATIC_ASSERT(EFX_NIC_FUNC_PRIMARY ==
+ (1u << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY));
+ EFX_STATIC_ASSERT(EFX_NIC_FUNC_LINKCTRL ==
+ (1u << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL));
+ EFX_STATIC_ASSERT(EFX_NIC_FUNC_TRUSTED ==
+ (1u << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED));
+
+ /* Save function privilege flags (EF10 and later) */
+ if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_EXT_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+ flags = MCDI_OUT_DWORD(req, DRV_ATTACH_EXT_OUT_FUNC_FLAGS);
+ }
+ encp->enc_func_flags = flags;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_get_board_cfg(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *board_typep,
+ __out_opt efx_dword_t *capabilitiesp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6])
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
+ MC_CMD_GET_BOARD_CFG_OUT_LENMIN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_BOARD_CFG;
req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
+ req.emr_in_length = MC_CMD_GET_BOARD_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LENMIN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_BOARD_CFG_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (mac_addrp != NULL) {
+ uint8_t *addrp;
+
+ if (emip->emi_port == 1) {
+ addrp = MCDI_OUT2(req, uint8_t,
+ GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0);
+ } else if (emip->emi_port == 2) {
+ addrp = MCDI_OUT2(req, uint8_t,
+ GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1);
+ } else {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ EFX_MAC_ADDR_COPY(mac_addrp, addrp);
+ }
+
+ if (capabilitiesp != NULL) {
+ if (emip->emi_port == 1) {
+ *capabilitiesp = *MCDI_OUT2(req, efx_dword_t,
+ GET_BOARD_CFG_OUT_CAPABILITIES_PORT0);
+ } else if (emip->emi_port == 2) {
+ *capabilitiesp = *MCDI_OUT2(req, efx_dword_t,
+ GET_BOARD_CFG_OUT_CAPABILITIES_PORT1);
+ } else {
+ rc = EINVAL;
+ goto fail4;
+ }
+ }
+
+ if (board_typep != NULL) {
+ *board_typep = MCDI_OUT_DWORD(req,
+ GET_BOARD_CFG_OUT_BOARD_TYPE);
+ }
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_get_resource_limits(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *nevqp,
+ __out_opt uint32_t *nrxqp,
+ __out_opt uint32_t *ntxqp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN,
+ MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_RESOURCE_LIMITS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (nevqp != NULL)
+ *nevqp = MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_EVQ);
+ if (nrxqp != NULL)
+ *nrxqp = MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_RXQ);
+ if (ntxqp != NULL)
+ *ntxqp = MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_TXQ);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_get_phy_cfg(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PHY_CFG_IN_LEN,
+ MC_CMD_GET_PHY_CFG_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PHY_CFG;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PHY_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PHY_CFG_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ encp->enc_phy_type = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_TYPE);
+#if EFSYS_OPT_NAMES
+ (void) strncpy(encp->enc_phy_name,
+ MCDI_OUT2(req, char, GET_PHY_CFG_OUT_NAME),
+ MIN(sizeof (encp->enc_phy_name) - 1,
+ MC_CMD_GET_PHY_CFG_OUT_NAME_LEN));
+#endif /* EFSYS_OPT_NAMES */
+ (void) memset(encp->enc_phy_revision, 0,
+ sizeof (encp->enc_phy_revision));
+ memcpy(encp->enc_phy_revision,
+ MCDI_OUT2(req, char, GET_PHY_CFG_OUT_REVISION),
+ MIN(sizeof (encp->enc_phy_revision) - 1,
+ MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN));
+#if EFSYS_OPT_PHY_LED_CONTROL
+ encp->enc_led_mask = ((1 << EFX_PHY_LED_DEFAULT) |
+ (1 << EFX_PHY_LED_OFF) |
+ (1 << EFX_PHY_LED_ON));
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
+#if EFSYS_OPT_PHY_PROPS
+ encp->enc_phy_nprops = 0;
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+ /* Get the media type of the fixed port, if recognised. */
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_XAUI == EFX_PHY_MEDIA_XAUI);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_CX4 == EFX_PHY_MEDIA_CX4);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_KX4 == EFX_PHY_MEDIA_KX4);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_XFP == EFX_PHY_MEDIA_XFP);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_SFP_PLUS == EFX_PHY_MEDIA_SFP_PLUS);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_BASE_T == EFX_PHY_MEDIA_BASE_T);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_QSFP_PLUS == EFX_PHY_MEDIA_QSFP_PLUS);
+ epp->ep_fixed_port_type =
+ MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_MEDIA_TYPE);
+ if (epp->ep_fixed_port_type >= EFX_PHY_MEDIA_NTYPES)
+ epp->ep_fixed_port_type = EFX_PHY_MEDIA_INVALID;
+
+ epp->ep_phy_cap_mask =
+ MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_SUPPORTED_CAP);
+#if EFSYS_OPT_PHY_FLAGS
+ encp->enc_phy_flags_mask = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_FLAGS);
+#endif /* EFSYS_OPT_PHY_FLAGS */
+
+ encp->enc_port = (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_PRT);
+
+ /* Populate internal state */
+ encp->enc_mcdi_mdio_channel =
+ (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_CHANNEL);
+
+#if EFSYS_OPT_PHY_STATS
+ encp->enc_mcdi_phy_stat_mask =
+ MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_STATS_MASK);
+#endif /* EFSYS_OPT_PHY_STATS */
+
+#if EFSYS_OPT_BIST
+ encp->enc_bist_mask = 0;
+ if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+ GET_PHY_CFG_OUT_BIST_CABLE_SHORT))
+ encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_CABLE_SHORT);
+ if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+ GET_PHY_CFG_OUT_BIST_CABLE_LONG))
+ encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_CABLE_LONG);
+ if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+ GET_PHY_CFG_OUT_BIST))
+ encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_NORMAL);
+#endif /* EFSYS_OPT_BIST */
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+efx_mcdi_firmware_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ int rc;
+
+ if (emcop != NULL && emcop->emco_fw_update_supported != NULL) {
+ if ((rc = emcop->emco_fw_update_supported(enp, supportedp))
+ != 0)
+ goto fail1;
+ } else {
+ /* Earlier devices always supported updates */
+ *supportedp = B_TRUE;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ int rc;
+
+ if (emcop != NULL && emcop->emco_macaddr_change_supported != NULL) {
+ if ((rc = emcop->emco_macaddr_change_supported(enp, supportedp))
+ != 0)
+ goto fail1;
+ } else {
+ /* Earlier devices always supported MAC changes */
+ *supportedp = B_TRUE;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#if EFSYS_OPT_BIST
+
+#if EFSYS_OPT_HUNTINGTON
+/*
+ * Enter bist offline mode. This is a fw mode which puts the NIC into a state
+ * where memory BIST tests can be run and not much else can interfere or happen.
+ * A reboot is required to exit this mode.
+ */
+ __checkReturn int
+efx_mcdi_bist_enable_offline(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ int rc;
+
+ EFX_STATIC_ASSERT(MC_CMD_ENABLE_OFFLINE_BIST_IN_LEN == 0);
+ EFX_STATIC_ASSERT(MC_CMD_ENABLE_OFFLINE_BIST_OUT_LEN == 0);
+
+ req.emr_cmd = MC_CMD_ENABLE_OFFLINE_BIST;
+ req.emr_in_buf = NULL;
+ req.emr_in_length = 0;
req.emr_out_buf = NULL;
req.emr_out_length = 0;
- MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS, 0);
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ __checkReturn int
+efx_mcdi_bist_start(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_START_BIST_IN_LEN,
+ MC_CMD_START_BIST_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_START_BIST;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_START_BIST_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_START_BIST_OUT_LEN;
+
+ switch (type) {
+ case EFX_BIST_TYPE_PHY_NORMAL:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE, MC_CMD_PHY_BIST);
+ break;
+ case EFX_BIST_TYPE_PHY_CABLE_SHORT:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_PHY_BIST_CABLE_SHORT);
+ break;
+ case EFX_BIST_TYPE_PHY_CABLE_LONG:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_PHY_BIST_CABLE_LONG);
+ break;
+ case EFX_BIST_TYPE_MC_MEM:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_MC_MEM_BIST);
+ break;
+ case EFX_BIST_TYPE_SAT_MEM:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_PORT_MEM_BIST);
+ break;
+ case EFX_BIST_TYPE_REG:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_REG_BIST);
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ }
efx_mcdi_execute(enp, &req);
- /* Invert EIO */
- if (req.emr_rc != EIO) {
- rc = EIO;
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
goto fail1;
}
@@ -679,64 +1269,391 @@ fail1:
return (rc);
}
- __checkReturn boolean_t
-efx_mcdi_request_abort(
+#endif /* EFSYS_OPT_BIST */
+
+
+/* Enable logging of some events (e.g. link state changes) */
+ __checkReturn int
+efx_mcdi_log_ctrl(
__in efx_nic_t *enp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_mcdi_req_t *emrp;
- boolean_t aborted;
- int state;
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_LOG_CTRL_IN_LEN,
+ MC_CMD_LOG_CTRL_OUT_LEN)];
+ int rc;
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
- EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LOG_CTRL;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_LOG_CTRL_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST,
+ MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ);
+ MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST_EVQ, 0);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+#if EFSYS_OPT_MAC_STATS
+
+typedef enum efx_stats_action_e
+{
+ EFX_STATS_CLEAR,
+ EFX_STATS_UPLOAD,
+ EFX_STATS_ENABLE_NOEVENTS,
+ EFX_STATS_ENABLE_EVENTS,
+ EFX_STATS_DISABLE,
+} efx_stats_action_t;
+
+static __checkReturn int
+efx_mcdi_mac_stats(
+ __in efx_nic_t *enp,
+ __in_opt efsys_mem_t *esmp,
+ __in efx_stats_action_t action)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_MAC_STATS_IN_LEN,
+ MC_CMD_MAC_STATS_OUT_DMA_LEN)];
+ int clear = (action == EFX_STATS_CLEAR);
+ int upload = (action == EFX_STATS_UPLOAD);
+ int enable = (action == EFX_STATS_ENABLE_NOEVENTS);
+ int events = (action == EFX_STATS_ENABLE_EVENTS);
+ int disable = (action == EFX_STATS_DISABLE);
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_MAC_STATS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_MAC_STATS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_MAC_STATS_OUT_DMA_LEN;
+
+ MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD,
+ MAC_STATS_IN_DMA, upload,
+ MAC_STATS_IN_CLEAR, clear,
+ MAC_STATS_IN_PERIODIC_CHANGE, enable | events | disable,
+ MAC_STATS_IN_PERIODIC_ENABLE, enable | events,
+ MAC_STATS_IN_PERIODIC_NOEVENT, !events,
+ MAC_STATS_IN_PERIOD_MS, (enable | events) ? 1000: 0);
+
+ if (esmp != NULL) {
+ int bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
+
+ EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <=
+ EFX_MAC_STATS_SIZE);
+
+ MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
+ EFSYS_MEM_ADDR(esmp) & 0xffffffff);
+ MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
+ EFSYS_MEM_ADDR(esmp) >> 32);
+ MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
+ } else {
+ EFSYS_ASSERT(!upload && !enable && !events);
+ }
/*
- * efx_mcdi_ev_* may have already completed this event, and be
- * spinning/blocked on the upper layer lock. So it *is* legitimate
- * to for emi_pending_req to be NULL. If there is a pending event
- * completed request, then provide a "credit" to allow
- * efx_mcdi_ev_cpl() to accept a single spurious completion.
+ * NOTE: Do not use EVB_PORT_ID_ASSIGNED when disabling periodic stats,
+ * as this may fail (and leave periodic DMA enabled) if the
+ * vadapter has already been deleted.
*/
- EFSYS_LOCK(enp->en_eslp, state);
- emrp = emip->emi_pending_req;
- aborted = (emrp != NULL);
- if (aborted) {
- emip->emi_pending_req = NULL;
+ MCDI_IN_SET_DWORD(req, MAC_STATS_IN_PORT_ID,
+ (disable ? EVB_PORT_ID_NULL : enp->en_vport_id));
- /* Error the request */
- emrp->emr_out_length_used = 0;
- emrp->emr_rc = ETIMEDOUT;
-
- /* Provide a credit for seqno/emr_pending_req mismatches */
- if (emip->emi_ev_cpl)
- ++emip->emi_aborted;
+ efx_mcdi_execute(enp, &req);
- /*
- * The upper layer has called us, so we don't
- * need to complete the request.
- */
+ if (req.emr_rc != 0) {
+ /* EF10: Expect ENOENT if no DMA queues are initialised */
+ if ((req.emr_rc != ENOENT) ||
+ (enp->en_rx_qcount + enp->en_tx_qcount != 0)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
}
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (aborted);
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
}
- void
-efx_mcdi_fini(
+ __checkReturn int
+efx_mcdi_mac_stats_clear(
__in efx_nic_t *enp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ int rc;
- EFSYS_ASSERT3U(enp->en_mod_flags, ==, EFX_MOD_MCDI);
- enp->en_mod_flags &= ~EFX_MOD_MCDI;
+ if ((rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_CLEAR)) != 0)
+ goto fail1;
- if (~(enp->en_features) & EFX_FEATURE_MCDI)
- return;
+ return (0);
- emip->emi_mtp = NULL;
- emip->emi_port = 0;
- emip->emi_aborted = 0;
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
}
+ __checkReturn int
+efx_mcdi_mac_stats_upload(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp)
+{
+ int rc;
+
+ /*
+ * The MC DMAs aggregate statistics for our convenience, so we can
+ * avoid having to pull the statistics buffer into the cache to
+ * maintain cumulative statistics.
+ */
+ if ((rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_UPLOAD)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_mac_stats_periodic(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __in uint16_t period,
+ __in boolean_t events)
+{
+ int rc;
+
+ /*
+ * The MC DMAs aggregate statistics for our convenience, so we can
+ * avoid having to pull the statistics buffer into the cache to
+ * maintain cumulative statistics.
+ * Huntington uses a fixed 1sec period, so use that on Siena too.
+ */
+ if (period == 0)
+ rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_DISABLE);
+ else if (events)
+ rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_EVENTS);
+ else
+ rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_NOEVENTS);
+
+ if (rc != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_MAC_STATS */
+
+#if EFSYS_OPT_HUNTINGTON
+
+/*
+ * This function returns the pf and vf number of a function. If it is a pf the
+ * vf number is 0xffff. The vf number is the index of the vf on that
+ * function. So if you have 3 vfs on pf 0 the 3 vfs will return (pf=0,vf=0),
+ * (pf=0,vf=1), (pf=0,vf=2) aand the pf will return (pf=0, vf=0xffff).
+ */
+ __checkReturn int
+efx_mcdi_get_function_info(
+ __in efx_nic_t *enp,
+ __out uint32_t *pfp,
+ __out_opt uint32_t *vfp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_FUNCTION_INFO_IN_LEN,
+ MC_CMD_GET_FUNCTION_INFO_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_FUNCTION_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_FUNCTION_INFO_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_FUNCTION_INFO_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_FUNCTION_INFO_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *pfp = MCDI_OUT_DWORD(req, GET_FUNCTION_INFO_OUT_PF);
+ if (vfp != NULL)
+ *vfp = MCDI_OUT_DWORD(req, GET_FUNCTION_INFO_OUT_VF);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_privilege_mask(
+ __in efx_nic_t *enp,
+ __in uint32_t pf,
+ __in uint32_t vf,
+ __out uint32_t *maskp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_PRIVILEGE_MASK_IN_LEN,
+ MC_CMD_PRIVILEGE_MASK_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_PRIVILEGE_MASK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_PRIVILEGE_MASK_OUT_LEN;
+
+ MCDI_IN_POPULATE_DWORD_2(req, PRIVILEGE_MASK_IN_FUNCTION,
+ PRIVILEGE_MASK_IN_FUNCTION_PF, pf,
+ PRIVILEGE_MASK_IN_FUNCTION_VF, vf);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_PRIVILEGE_MASK_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *maskp = MCDI_OUT_DWORD(req, PRIVILEGE_MASK_OUT_OLD_MASK);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ __checkReturn int
+efx_mcdi_set_workaround(
+ __in efx_nic_t *enp,
+ __in uint32_t type,
+ __in boolean_t enabled,
+ __out_opt uint32_t *flagsp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_WORKAROUND_IN_LEN,
+ MC_CMD_WORKAROUND_EXT_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_WORKAROUND;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_WORKAROUND_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_WORKAROUND_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, WORKAROUND_IN_TYPE, type);
+ MCDI_IN_SET_DWORD(req, WORKAROUND_IN_ENABLED, enabled ? 1 : 0);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (flagsp != NULL) {
+ if (req.emr_out_length_used >= MC_CMD_WORKAROUND_EXT_OUT_LEN)
+ *flagsp = MCDI_OUT_DWORD(req, WORKAROUND_EXT_OUT_FLAGS);
+ else
+ *flagsp = 0;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+efx_mcdi_get_workarounds(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *implementedp,
+ __out_opt uint32_t *enabledp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MC_CMD_GET_WORKAROUNDS_OUT_LEN];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_WORKAROUNDS;
+ req.emr_in_buf = NULL;
+ req.emr_in_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_WORKAROUNDS_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (implementedp != NULL) {
+ *implementedp =
+ MCDI_OUT_DWORD(req, GET_WORKAROUNDS_OUT_IMPLEMENTED);
+ }
+
+ if (enabledp != NULL) {
+ *enabledp = MCDI_OUT_DWORD(req, GET_WORKAROUNDS_OUT_ENABLED);
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
#endif /* EFSYS_OPT_MCDI */
diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h
index b1157466495b..ea0224878162 100644
--- a/sys/dev/sfxge/common/efx_mcdi.h
+++ b/sys/dev/sfxge/common/efx_mcdi.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -36,10 +41,15 @@
extern "C" {
#endif
-/* Number of retries attempted for init code */
-#define EFX_MCDI_REQ_RETRY_INIT 2
+/*
+ * A reboot/assertion causes the MCDI status word to be set after the
+ * command word is set or a REBOOT event is sent. If we notice a reboot
+ * via these mechanisms then wait 10ms for the status word to be set.
+ */
+#define EFX_MCDI_STATUS_SLEEP_US 10000
struct efx_mcdi_req_s {
+ boolean_t emr_quiet;
/* Inputs: Command #, input buffer and length */
unsigned int emr_cmd;
uint8_t *emr_in_buf;
@@ -52,19 +62,25 @@ struct efx_mcdi_req_s {
};
typedef struct efx_mcdi_iface_s {
- const efx_mcdi_transport_t *emi_mtp;
unsigned int emi_port;
unsigned int emi_seq;
efx_mcdi_req_t *emi_pending_req;
boolean_t emi_ev_cpl;
+ boolean_t emi_new_epoch;
int emi_aborted;
uint32_t emi_poll_cnt;
+ uint32_t emi_mc_reboot_status;
} efx_mcdi_iface_t;
extern void
efx_mcdi_execute(
__in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp);
+ __inout efx_mcdi_req_t *emrp);
+
+extern void
+efx_mcdi_execute_quiet(
+ __in efx_nic_t *enp,
+ __inout efx_mcdi_req_t *emrp);
extern void
efx_mcdi_ev_cpl(
@@ -78,6 +94,16 @@ efx_mcdi_ev_death(
__in efx_nic_t *enp,
__in int rc);
+extern __checkReturn int
+efx_mcdi_request_errcode(
+ __in unsigned int err);
+
+extern void
+efx_mcdi_raise_exception(
+ __in efx_nic_t *enp,
+ __in_opt efx_mcdi_req_t *emrp,
+ __in int rc);
+
typedef enum efx_mcdi_boot_e {
EFX_MCDI_BOOT_PRIMARY,
EFX_MCDI_BOOT_SECONDARY,
@@ -91,6 +117,86 @@ efx_mcdi_version(
__out_opt uint32_t *buildp,
__out_opt efx_mcdi_boot_t *statusp);
+extern __checkReturn int
+efx_mcdi_read_assertion(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_exit_assertion_handler(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_drv_attach(
+ __in efx_nic_t *enp,
+ __in boolean_t attach);
+
+extern __checkReturn int
+efx_mcdi_get_board_cfg(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *board_typep,
+ __out_opt efx_dword_t *capabilitiesp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6]);
+
+extern __checkReturn int
+efx_mcdi_get_phy_cfg(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_firmware_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+extern __checkReturn int
+efx_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+#if EFSYS_OPT_BIST
+#if EFSYS_OPT_HUNTINGTON
+extern __checkReturn int
+efx_mcdi_bist_enable_offline(
+ __in efx_nic_t *enp);
+#endif /* EFSYS_OPT_HUNTINGTON */
+extern __checkReturn int
+efx_mcdi_bist_start(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type);
+#endif /* EFSYS_OPT_BIST */
+
+extern __checkReturn int
+efx_mcdi_get_resource_limits(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *nevqp,
+ __out_opt uint32_t *nrxqp,
+ __out_opt uint32_t *ntxqp);
+
+extern __checkReturn int
+efx_mcdi_log_ctrl(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_mac_stats_clear(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_mac_stats_upload(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp);
+
+extern __checkReturn int
+efx_mcdi_mac_stats_periodic(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __in uint16_t period,
+ __in boolean_t events);
+
+
+#if EFSYS_OPT_LOOPBACK
+extern __checkReturn int
+efx_mcdi_get_loopback_modes(
+ __in efx_nic_t *enp);
+#endif /* EFSYS_OPT_LOOPBACK */
+
#define MCDI_IN(_emr, _type, _ofst) \
((_type *)((_emr).emr_in_buf + (_ofst)))
@@ -101,10 +207,18 @@ efx_mcdi_version(
EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst), \
EFX_BYTE_0, _value)
+#define MCDI_IN_SET_WORD(_emr, _ofst, _value) \
+ EFX_POPULATE_WORD_1(*MCDI_IN2(_emr, efx_word_t, _ofst), \
+ EFX_WORD_0, _value)
+
#define MCDI_IN_SET_DWORD(_emr, _ofst, _value) \
EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \
EFX_DWORD_0, _value)
+#define MCDI_IN_SET_DWORD_FIELD(_emr, _ofst, _field, _value) \
+ EFX_SET_DWORD_FIELD(*MCDI_IN2(_emr, efx_dword_t, _ofst), \
+ MC_CMD_ ## _field, _value)
+
#define MCDI_IN_POPULATE_DWORD_1(_emr, _ofst, _field1, _value1) \
EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \
MC_CMD_ ## _field1, _value1)
@@ -154,7 +268,7 @@ efx_mcdi_version(
#define MCDI_IN_POPULATE_DWORD_7(_emr, _ofst, _field1, _value1, \
_field2, _value2, _field3, _value3, _field4, _value4, \
_field5, _value5, _field6, _value6, _field7, _value7) \
- EFX_POPULATE_DWORD_7(MCDI_IN2(_emr, efx_dword_t, _ofst), \
+ EFX_POPULATE_DWORD_7(*MCDI_IN2(_emr, efx_dword_t, _ofst), \
MC_CMD_ ## _field1, _value1, \
MC_CMD_ ## _field2, _value2, \
MC_CMD_ ## _field3, _value3, \
@@ -233,7 +347,7 @@ efx_mcdi_version(
#define MCDI_EV_FIELD(_eqp, _field) \
EFX_QWORD_FIELD(*_eqp, MCDI_EVENT_ ## _field)
-#define MCDI_CMD_DWORD_FIELD(_edp, _field) \
+#define MCDI_CMD_DWORD_FIELD(_edp, _field) \
EFX_DWORD_FIELD(*_edp, MC_CMD_ ## _field)
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/efx_mon.c b/sys/dev/sfxge/common/efx_mon.c
index dc2e25603e7e..c5b356d687a9 100644
--- a/sys/dev/sfxge/common/efx_mon.c
+++ b/sys/dev/sfxge/common/efx_mon.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -44,17 +49,22 @@ __FBSDID("$FreeBSD$");
#include "max6647.h"
#endif
+#if EFSYS_OPT_MON_MCDI
+#include "mcdi_mon.h"
+#endif
+
#if EFSYS_OPT_NAMES
-static const char __cs * __cs __efx_mon_name[] = {
+static const char *__efx_mon_name[] = {
"",
"nullmon",
"lm87",
"max6647",
- "sfx90x0"
+ "sfx90x0",
+ "sfx91x0"
};
- const char __cs *
+ const char *
efx_mon_name(
__in efx_nic_t *enp)
{
@@ -70,47 +80,46 @@ efx_mon_name(
#endif /* EFSYS_OPT_NAMES */
#if EFSYS_OPT_MON_NULL
-static efx_mon_ops_t __cs __efx_mon_null_ops = {
+static efx_mon_ops_t __efx_mon_null_ops = {
nullmon_reset, /* emo_reset */
nullmon_reconfigure, /* emo_reconfigure */
#if EFSYS_OPT_MON_STATS
- nullmon_stats_update /* emo_stat_update */
+ nullmon_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
#if EFSYS_OPT_MON_LM87
-static efx_mon_ops_t __cs __efx_mon_lm87_ops = {
+static efx_mon_ops_t __efx_mon_lm87_ops = {
lm87_reset, /* emo_reset */
lm87_reconfigure, /* emo_reconfigure */
#if EFSYS_OPT_MON_STATS
- lm87_stats_update /* emo_stat_update */
+ lm87_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
#if EFSYS_OPT_MON_MAX6647
-static efx_mon_ops_t __cs __efx_mon_max6647_ops = {
+static efx_mon_ops_t __efx_mon_max6647_ops = {
max6647_reset, /* emo_reset */
max6647_reconfigure, /* emo_reconfigure */
#if EFSYS_OPT_MON_STATS
- max6647_stats_update /* emo_stat_update */
+ max6647_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
-#if EFSYS_OPT_MON_SIENA
-static efx_mon_ops_t __cs __efx_mon_siena_ops = {
- siena_mon_reset, /* emo_reset */
- siena_mon_reconfigure, /* emo_reconfigure */
+#if EFSYS_OPT_MON_MCDI
+static efx_mon_ops_t __efx_mon_mcdi_ops = {
+ NULL, /* emo_reset */
+ NULL, /* emo_reconfigure */
#if EFSYS_OPT_MON_STATS
- siena_mon_stats_update /* emo_stat_update */
+ mcdi_mon_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
-
-static efx_mon_ops_t __cs * __cs __efx_mon_ops[] = {
+static efx_mon_ops_t *__efx_mon_ops[] = {
NULL,
#if EFSYS_OPT_MON_NULL
&__efx_mon_null_ops,
@@ -127,8 +136,13 @@ static efx_mon_ops_t __cs * __cs __efx_mon_ops[] = {
#else
NULL,
#endif
-#if EFSYS_OPT_MON_SIENA
- &__efx_mon_siena_ops
+#if EFSYS_OPT_MON_MCDI
+ &__efx_mon_mcdi_ops,
+#else
+ NULL,
+#endif
+#if EFSYS_OPT_MON_MCDI
+ &__efx_mon_mcdi_ops
#else
NULL
#endif
@@ -162,11 +176,15 @@ efx_mon_init(
goto fail2;
}
- if ((rc = emop->emo_reset(enp)) != 0)
- goto fail3;
+ if (emop->emo_reset != NULL) {
+ if ((rc = emop->emo_reset(enp)) != 0)
+ goto fail3;
+ }
- if ((rc = emop->emo_reconfigure(enp)) != 0)
- goto fail4;
+ if (emop->emo_reconfigure != NULL) {
+ if ((rc = emop->emo_reconfigure(enp)) != 0)
+ goto fail4;
+ }
emp->em_emop = emop;
return (0);
@@ -174,7 +192,8 @@ efx_mon_init(
fail4:
EFSYS_PROBE(fail5);
- (void) emop->emo_reset(enp);
+ if (emop->emo_reset != NULL)
+ (void) emop->emo_reset(enp);
fail3:
EFSYS_PROBE(fail4);
@@ -195,8 +214,8 @@ fail1:
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED MonitorStatNamesBlock 89ff37f1d74ad8b3 */
-static const char __cs * __cs __mon_stat_name[] = {
+/* START MKCONFIG GENERATED MonitorStatNamesBlock b9328f15438c4d01 */
+static const char *__mon_stat_name[] = {
"value_2_5v",
"value_vccp1",
"value_vcc",
@@ -227,11 +246,50 @@ static const char __cs * __cs __mon_stat_name[] = {
"vaoe_in",
"iaoe",
"iaoe_in",
+ "nic_power",
+ "0_9v",
+ "i0_9v",
+ "i1_2v",
+ "0_9v_adc",
+ "controller_temperature2",
+ "vreg_temperature",
+ "vreg_0_9v_temperature",
+ "vreg_1_2v_temperature",
+ "int_vptat",
+ "controller_internal_adc_temperature",
+ "ext_vptat",
+ "controller_external_adc_temperature",
+ "ambient_temperature",
+ "airflow",
+ "vdd08d_vss08d_csr",
+ "vdd08d_vss08d_csr_extadc",
+ "hotpoint_temperature",
+ "phy_power_switch_port0",
+ "phy_power_switch_port1",
+ "mum_vcc",
+ "0v9_a",
+ "i0v9_a",
+ "0v9_a_temp",
+ "0v9_b",
+ "i0v9_b",
+ "0v9_b_temp",
+ "ccom_avreg_1v2_supply",
+ "ccom_avreg_1v2_supply_ext_adc",
+ "ccom_avreg_1v8_supply",
+ "ccom_avreg_1v8_supply_ext_adc",
+ "controller_master_vptat",
+ "controller_master_internal_temp",
+ "controller_master_vptat_ext_adc",
+ "controller_master_internal_temp_ext_adc",
+ "controller_slave_vptat",
+ "controller_slave_internal_temp",
+ "controller_slave_vptat_ext_adc",
+ "controller_slave_internal_temp_ext_adc",
};
/* END MKCONFIG GENERATED MonitorStatNamesBlock */
-extern const char __cs *
+extern const char *
efx_mon_stat_name(
__in efx_nic_t *enp,
__in efx_mon_stat_t id)
@@ -276,9 +334,11 @@ efx_mon_fini(
emp->em_emop = NULL;
- rc = emop->emo_reset(enp);
- if (rc != 0)
- EFSYS_PROBE1(fail1, int, rc);
+ if (emop->emo_reset != NULL) {
+ rc = emop->emo_reset(enp);
+ if (rc != 0)
+ EFSYS_PROBE1(fail1, int, rc);
+ }
emp->em_type = EFX_MON_INVALID;
diff --git a/sys/dev/sfxge/common/efx_nic.c b/sys/dev/sfxge/common/efx_nic.c
index b0ba58ccfc7a..b5ad65ead44c 100644
--- a/sys/dev/sfxge/common/efx_nic.c
+++ b/sys/dev/sfxge/common/efx_nic.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -38,27 +43,55 @@ efx_family(
__in uint16_t devid,
__out efx_family_t *efp)
{
+ if (venid == EFX_PCI_VENID_SFC) {
+ switch (devid) {
#if EFSYS_OPT_FALCON
- if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_FALCON) {
- *efp = EFX_FAMILY_FALCON;
- return (0);
- }
+ case EFX_PCI_DEVID_FALCON:
+ *efp = EFX_FAMILY_FALCON;
+ return (0);
#endif
#if EFSYS_OPT_SIENA
- if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_BETHPAGE) {
- *efp = EFX_FAMILY_SIENA;
- return (0);
- }
- if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_SIENA) {
- *efp = EFX_FAMILY_SIENA;
- return (0);
- }
- if (venid == EFX_PCI_VENID_SFC &&
- devid == EFX_PCI_DEVID_SIENA_F1_UNINIT) {
- *efp = EFX_FAMILY_SIENA;
- return (0);
- }
+ case EFX_PCI_DEVID_SIENA_F1_UNINIT:
+ /*
+ * Hardware default for PF0 of uninitialised Siena.
+ * manftest must be able to cope with this device id.
+ */
+ *efp = EFX_FAMILY_SIENA;
+ return (0);
+
+ case EFX_PCI_DEVID_BETHPAGE:
+ case EFX_PCI_DEVID_SIENA:
+ *efp = EFX_FAMILY_SIENA;
+ return (0);
+#endif
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT:
+ /*
+ * Hardware default for PF0 of uninitialised Huntington.
+ * manftest must be able to cope with this device id.
+ */
+ *efp = EFX_FAMILY_HUNTINGTON;
+ return (0);
+
+ case EFX_PCI_DEVID_FARMINGDALE:
+ case EFX_PCI_DEVID_GREENPORT:
+ case EFX_PCI_DEVID_HUNTINGTON:
+ *efp = EFX_FAMILY_HUNTINGTON;
+ return (0);
+
+ case EFX_PCI_DEVID_FARMINGDALE_VF:
+ case EFX_PCI_DEVID_GREENPORT_VF:
+ case EFX_PCI_DEVID_HUNTINGTON_VF:
+ *efp = EFX_FAMILY_HUNTINGTON;
+ return (0);
#endif
+ default:
+ break;
+ }
+ }
+
+ *efp = EFX_FAMILY_INVALID;
return (ENOTSUP);
}
@@ -80,11 +113,28 @@ efx_infer_family(
EFSYS_BAR_READO(esbp, FR_AZ_CS_DEBUG_REG_OFST, &oword, B_TRUE);
portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);
switch (portnum) {
+ case 0: {
+ efx_dword_t dword;
+ uint32_t hw_rev;
+
+ EFSYS_BAR_READD(esbp, ER_DZ_BIU_HW_REV_ID_REG_OFST, &dword,
+ B_TRUE);
+ hw_rev = EFX_DWORD_FIELD(dword, ERF_DZ_HW_REV_ID);
+ if (hw_rev == ER_DZ_BIU_HW_REV_ID_REG_RESET) {
+#if EFSYS_OPT_HUNTINGTON
+ family = EFX_FAMILY_HUNTINGTON;
+ break;
+#endif
+ } else {
#if EFSYS_OPT_FALCON
- case 0:
- family = EFX_FAMILY_FALCON;
- break;
+ family = EFX_FAMILY_FALCON;
+ break;
#endif
+ }
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
#if EFSYS_OPT_SIENA
case 1:
case 2:
@@ -106,15 +156,10 @@ fail1:
return (rc);
}
-/*
- * The built-in default value device id for port 1 of Siena is 0x0810.
- * manftest needs to be able to cope with that.
- */
-
#define EFX_BIU_MAGIC0 0x01234567
#define EFX_BIU_MAGIC1 0xfedcba98
-static __checkReturn int
+ __checkReturn int
efx_nic_biu_test(
__in efx_nic_t *enp)
{
@@ -128,18 +173,18 @@ efx_nic_biu_test(
* back the cached value that was last written.
*/
EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
- EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword);
+ EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
rc = EIO;
goto fail1;
}
- EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword);
+ EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
rc = EIO;
goto fail2;
@@ -151,18 +196,18 @@ efx_nic_biu_test(
* values already written into the scratch registers.
*/
EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
- EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword);
+ EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
rc = EIO;
goto fail3;
}
- EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword);
+ EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
rc = EIO;
goto fail4;
@@ -184,10 +229,13 @@ fail1:
#if EFSYS_OPT_FALCON
-static efx_nic_ops_t __cs __efx_nic_falcon_ops = {
+static efx_nic_ops_t __efx_nic_falcon_ops = {
falcon_nic_probe, /* eno_probe */
+ NULL, /* eno_set_drv_limits */
falcon_nic_reset, /* eno_reset */
falcon_nic_init, /* eno_init */
+ NULL, /* eno_get_vi_pool */
+ NULL, /* eno_get_bar_region */
#if EFSYS_OPT_DIAG
falcon_sram_test, /* eno_sram_test */
falcon_nic_register_test, /* eno_register_test */
@@ -200,10 +248,13 @@ static efx_nic_ops_t __cs __efx_nic_falcon_ops = {
#if EFSYS_OPT_SIENA
-static efx_nic_ops_t __cs __efx_nic_siena_ops = {
+static efx_nic_ops_t __efx_nic_siena_ops = {
siena_nic_probe, /* eno_probe */
+ NULL, /* eno_set_drv_limits */
siena_nic_reset, /* eno_reset */
siena_nic_init, /* eno_init */
+ NULL, /* eno_get_vi_pool */
+ NULL, /* eno_get_bar_region */
#if EFSYS_OPT_DIAG
siena_sram_test, /* eno_sram_test */
siena_nic_register_test, /* eno_register_test */
@@ -214,6 +265,25 @@ static efx_nic_ops_t __cs __efx_nic_siena_ops = {
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+
+static efx_nic_ops_t __efx_nic_hunt_ops = {
+ hunt_nic_probe, /* eno_probe */
+ hunt_nic_set_drv_limits, /* eno_set_drv_limits */
+ hunt_nic_reset, /* eno_reset */
+ hunt_nic_init, /* eno_init */
+ hunt_nic_get_vi_pool, /* eno_get_vi_pool */
+ hunt_nic_get_bar_region, /* eno_get_bar_region */
+#if EFSYS_OPT_DIAG
+ hunt_sram_test, /* eno_sram_test */
+ hunt_nic_register_test, /* eno_register_test */
+#endif /* EFSYS_OPT_DIAG */
+ hunt_nic_fini, /* eno_fini */
+ hunt_nic_unprobe, /* eno_unprobe */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_nic_create(
__in efx_family_t family,
@@ -257,10 +327,27 @@ efx_nic_create(
EFX_FEATURE_WOL |
EFX_FEATURE_MCDI |
EFX_FEATURE_LOOKAHEAD_SPLIT |
- EFX_FEATURE_MAC_HEADER_FILTERS;
+ EFX_FEATURE_MAC_HEADER_FILTERS |
+ EFX_FEATURE_TX_SRC_FILTERS;
break;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ enp->en_enop = (efx_nic_ops_t *)&__efx_nic_hunt_ops;
+ /* FIXME: Add WOL support */
+ enp->en_features =
+ EFX_FEATURE_IPV6 |
+ EFX_FEATURE_LINK_EVENTS |
+ EFX_FEATURE_PERIODIC_MAC_STATS |
+ EFX_FEATURE_MCDI |
+ EFX_FEATURE_MAC_HEADER_FILTERS |
+ EFX_FEATURE_MCDI_DMA |
+ EFX_FEATURE_PIO_BUFFERS |
+ EFX_FEATURE_FW_ASSISTED_TSO;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
default:
rc = ENOTSUP;
goto fail2;
@@ -276,7 +363,7 @@ efx_nic_create(
return (0);
fail2:
- EFSYS_PROBE(fail3);
+ EFSYS_PROBE(fail2);
enp->en_magic = 0;
@@ -294,7 +381,6 @@ efx_nic_probe(
__in efx_nic_t *enp)
{
efx_nic_ops_t *enop;
- efx_oword_t oword;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -303,36 +389,22 @@ efx_nic_probe(
#endif /* EFSYS_OPT_MCDI */
EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
- /* Test BIU */
- if ((rc = efx_nic_biu_test(enp)) != 0)
- goto fail1;
-
- /* Clear the region register */
- EFX_POPULATE_OWORD_4(oword,
- FRF_AZ_ADR_REGION0, 0,
- FRF_AZ_ADR_REGION1, (1 << 16),
- FRF_AZ_ADR_REGION2, (2 << 16),
- FRF_AZ_ADR_REGION3, (3 << 16));
- EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
-
enop = enp->en_enop;
if ((rc = enop->eno_probe(enp)) != 0)
- goto fail2;
+ goto fail1;
if ((rc = efx_phy_probe(enp)) != 0)
- goto fail3;
+ goto fail2;
enp->en_mod_flags |= EFX_MOD_PROBE;
return (0);
-fail3:
- EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
enop->eno_unprobe(enp);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
@@ -376,6 +448,105 @@ efx_nic_pcie_extended_sync(
#endif /* EFSYS_OPT_PCIE_TUNE */
__checkReturn int
+efx_nic_set_drv_limits(
+ __inout efx_nic_t *enp,
+ __in efx_drv_limits_t *edlp)
+{
+ efx_nic_ops_t *enop = enp->en_enop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+
+ if (enop->eno_set_drv_limits != NULL) {
+ if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_nic_get_bar_region(
+ __in efx_nic_t *enp,
+ __in efx_nic_region_t region,
+ __out uint32_t *offsetp,
+ __out size_t *sizep)
+{
+ efx_nic_ops_t *enop = enp->en_enop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+ if (enop->eno_get_bar_region == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ if ((rc = (enop->eno_get_bar_region)(enp,
+ region, offsetp, sizep)) != 0) {
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+efx_nic_get_vi_pool(
+ __in efx_nic_t *enp,
+ __out uint32_t *evq_countp,
+ __out uint32_t *rxq_countp,
+ __out uint32_t *txq_countp)
+{
+ efx_nic_ops_t *enop = enp->en_enop;
+ efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+ if (enop->eno_get_vi_pool != NULL) {
+ uint32_t vi_count = 0;
+
+ if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
+ goto fail1;
+
+ *evq_countp = vi_count;
+ *rxq_countp = vi_count;
+ *txq_countp = vi_count;
+ } else {
+ /* Use NIC limits as default value */
+ *evq_countp = encp->enc_evq_limit;
+ *rxq_countp = encp->enc_rxq_limit;
+ *txq_countp = encp->enc_txq_limit;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
efx_nic_init(
__in efx_nic_t *enp)
{
@@ -679,3 +850,191 @@ fail1:
}
#endif /* EFSYS_OPT_DIAG */
+
+#if EFSYS_OPT_LOOPBACK
+
+extern void
+efx_loopback_mask(
+ __in efx_loopback_kind_t loopback_kind,
+ __out efx_qword_t *maskp)
+{
+ efx_qword_t mask;
+
+ EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
+ EFSYS_ASSERT(maskp != NULL);
+
+ /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
+ EFX_LOOPBACK_XAUI_WS_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
+ EFX_LOOPBACK_XAUI_WS_NEAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
+ EFX_LOOPBACK_XFI_WS_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
+ EFX_LOOPBACK_PMA_INT_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
+ EFX_LOOPBACK_SD_FEP2_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
+ EFX_LOOPBACK_SD_FEP1_5_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
+
+ /* Build bitmask of possible loopback types */
+ EFX_ZERO_QWORD(mask);
+
+ if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
+ (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
+ }
+
+ if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
+ (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
+ /*
+ * The "MAC" grouping has historically been used by drivers to
+ * mean loopbacks supported by on-chip hardware. Keep that
+ * meaning here, and include on-chip PHY layer loopbacks.
+ */
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
+ }
+
+ if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
+ (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
+ /*
+ * The "PHY" grouping has historically been used by drivers to
+ * mean loopbacks supported by off-chip hardware. Keep that
+ * meaning here.
+ */
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
+ }
+
+ *maskp = mask;
+}
+
+__checkReturn int
+efx_mcdi_get_loopback_modes(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
+ MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
+ efx_qword_t mask;
+ efx_qword_t modes;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used <
+ MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
+ MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ /*
+ * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
+ * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
+ */
+ efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
+
+ EFX_AND_QWORD(mask,
+ *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
+
+ modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
+
+ modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
+
+ modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
+
+ if (req.emr_out_length_used >=
+ MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
+ MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
+ /* Response includes 40G loopback modes */
+ modes =
+ *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
+ }
+
+ EFX_ZERO_QWORD(modes);
+ EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
+ encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_LOOPBACK */
diff --git a/sys/dev/sfxge/common/efx_nvram.c b/sys/dev/sfxge/common/efx_nvram.c
index 2df9bb98b3ca..82bb1d9842f5 100644
--- a/sys/dev/sfxge/common/efx_nvram.c
+++ b/sys/dev/sfxge/common/efx_nvram.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -36,7 +41,7 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_FALCON
-static efx_nvram_ops_t __cs __efx_nvram_falcon_ops = {
+static efx_nvram_ops_t __efx_nvram_falcon_ops = {
#if EFSYS_OPT_DIAG
falcon_nvram_test, /* envo_test */
#endif /* EFSYS_OPT_DIAG */
@@ -54,7 +59,7 @@ static efx_nvram_ops_t __cs __efx_nvram_falcon_ops = {
#if EFSYS_OPT_SIENA
-static efx_nvram_ops_t __cs __efx_nvram_siena_ops = {
+static efx_nvram_ops_t __efx_nvram_siena_ops = {
#if EFSYS_OPT_DIAG
siena_nvram_test, /* envo_test */
#endif /* EFSYS_OPT_DIAG */
@@ -70,6 +75,24 @@ static efx_nvram_ops_t __cs __efx_nvram_siena_ops = {
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+
+static efx_nvram_ops_t __efx_nvram_hunt_ops = {
+#if EFSYS_OPT_DIAG
+ hunt_nvram_test, /* envo_test */
+#endif /* EFSYS_OPT_DIAG */
+ hunt_nvram_size, /* envo_size */
+ hunt_nvram_get_version, /* envo_get_version */
+ hunt_nvram_rw_start, /* envo_rw_start */
+ hunt_nvram_read_chunk, /* envo_read_chunk */
+ hunt_nvram_erase, /* envo_erase */
+ hunt_nvram_write_chunk, /* envo_write_chunk */
+ hunt_nvram_rw_finish, /* envo_rw_finish */
+ hunt_nvram_set_version, /* envo_set_version */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_nvram_init(
__in efx_nic_t *enp)
@@ -94,6 +117,12 @@ efx_nvram_init(
break;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ envop = (efx_nvram_ops_t *)&__efx_nvram_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
default:
EFSYS_ASSERT(0);
rc = ENOTSUP;
@@ -329,7 +358,7 @@ efx_nvram_rw_finish(
efx_nvram_set_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint16_t version[4])
+ __in_ecount(4) uint16_t version[4])
{
efx_nvram_ops_t *envop = enp->en_envop;
int rc;
@@ -373,3 +402,486 @@ efx_nvram_fini(
}
#endif /* EFSYS_OPT_NVRAM */
+
+#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
+
+/*
+ * Internal MCDI request handling
+ */
+
+ __checkReturn int
+efx_mcdi_nvram_partitions(
+ __in efx_nic_t *enp,
+ __out_bcount(size) caddr_t data,
+ __in size_t size,
+ __out unsigned int *npartnp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
+ MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
+ unsigned int npartn;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+ npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ if (size < npartn * sizeof (uint32_t)) {
+ rc = ENOSPC;
+ goto fail3;
+ }
+
+ *npartnp = npartn;
+
+ memcpy(data,
+ MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
+ (npartn * sizeof (uint32_t)));
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_metadata(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4],
+ __out_bcount_opt(size) char *descp,
+ __in size_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
+ MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_METADATA;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
+ NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
+ *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
+ } else {
+ *subtypep = 0;
+ }
+
+ if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
+ NVRAM_METADATA_OUT_VERSION_VALID)) {
+ version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
+ version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
+ version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
+ version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
+ } else {
+ version[0] = version[1] = version[2] = version[3] = 0;
+ }
+
+ if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
+ NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
+ /* Return optional descrition string */
+ if ((descp != NULL) && (size > 0)) {
+ size_t desclen;
+
+ descp[0] = '\0';
+ desclen = (req.emr_out_length_used
+ - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
+
+ EFSYS_ASSERT3U(desclen, <=,
+ MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
+
+ if (size < desclen) {
+ rc = ENOSPC;
+ goto fail3;
+ }
+
+ memcpy(descp, MCDI_OUT2(req, char,
+ NVRAM_METADATA_OUT_DESCRIPTION),
+ desclen);
+
+ /* Ensure string is NUL terminated */
+ descp[desclen] = '\0';
+ }
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_info(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __out_opt size_t *sizep,
+ __out_opt uint32_t *addressp,
+ __out_opt uint32_t *erase_sizep)
+{
+ uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
+ MC_CMD_NVRAM_INFO_OUT_LEN)];
+ efx_mcdi_req_t req;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_INFO_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (sizep)
+ *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
+
+ if (addressp)
+ *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
+
+ if (erase_sizep)
+ *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_update_start(
+ __in efx_nic_t *enp,
+ __in uint32_t partn)
+{
+ uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_IN_LEN,
+ MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
+ efx_mcdi_req_t req;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_read(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_LEN,
+ MC_CMD_NVRAM_READ_OUT_LENMAX)];
+ int rc;
+
+ if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_READ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_READ_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_OFFSET, offset);
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_LENGTH, size);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ memcpy(data,
+ MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
+ size);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_erase(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __in size_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
+ MC_CMD_NVRAM_ERASE_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_ERASE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
+ MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_write(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_WRITE_IN_LENMAX,
+ MC_CMD_NVRAM_WRITE_OUT_LEN)];
+ int rc;
+
+ if (size > MC_CMD_NVRAM_WRITE_IN_LENMAX) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_WRITE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
+ MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
+
+ memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
+ data, size);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_update_finish(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in boolean_t reboot)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN,
+ MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+efx_mcdi_nvram_test(
+ __in efx_nic_t *enp,
+ __in uint32_t partn)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
+ MC_CMD_NVRAM_TEST_OUT_LEN)];
+ int result;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_TEST;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
+ if (result == MC_CMD_NVRAM_TEST_FAIL) {
+
+ EFSYS_PROBE1(nvram_test_failure, int, partn);
+
+ rc = (EINVAL);
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+
+#endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */
diff --git a/sys/dev/sfxge/common/efx_phy.c b/sys/dev/sfxge/common/efx_phy.c
index bb34ea7bd99d..5d18dc70b97b 100644
--- a/sys/dev/sfxge/common/efx_phy.c
+++ b/sys/dev/sfxge/common/efx_phy.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -68,7 +73,7 @@ __FBSDID("$FreeBSD$");
#endif
#if EFSYS_OPT_PHY_NULL
-static efx_phy_ops_t __cs __efx_phy_null_ops = {
+static efx_phy_ops_t __efx_phy_null_ops = {
NULL, /* epo_power */
nullphy_reset, /* epo_reset */
nullphy_reconfigure, /* epo_reconfigure */
@@ -86,16 +91,17 @@ static efx_phy_ops_t __cs __efx_phy_null_ops = {
nullphy_prop_get, /* epo_prop_get */
nullphy_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_NULL */
#if EFSYS_OPT_PHY_QT2022C2
-static efx_phy_ops_t __cs __efx_phy_qt2022c2_ops = {
+static efx_phy_ops_t __efx_phy_qt2022c2_ops = {
NULL, /* epo_power */
qt2022c2_reset, /* epo_reset */
qt2022c2_reconfigure, /* epo_reconfigure */
@@ -113,16 +119,17 @@ static efx_phy_ops_t __cs __efx_phy_qt2022c2_ops = {
qt2022c2_prop_get, /* epo_prop_get */
qt2022c2_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_QT2022C2 */
#if EFSYS_OPT_PHY_SFX7101
-static efx_phy_ops_t __cs __efx_phy_sfx7101_ops = {
+static efx_phy_ops_t __efx_phy_sfx7101_ops = {
sfx7101_power, /* epo_power */
sfx7101_reset, /* epo_reset */
sfx7101_reconfigure, /* epo_reconfigure */
@@ -140,16 +147,17 @@ static efx_phy_ops_t __cs __efx_phy_sfx7101_ops = {
sfx7101_prop_get, /* epo_prop_get */
sfx7101_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_SFX7101 */
#if EFSYS_OPT_PHY_TXC43128
-static efx_phy_ops_t __cs __efx_phy_txc43128_ops = {
+static efx_phy_ops_t __efx_phy_txc43128_ops = {
NULL, /* epo_power */
txc43128_reset, /* epo_reset */
txc43128_reconfigure, /* epo_reconfigure */
@@ -167,16 +175,17 @@ static efx_phy_ops_t __cs __efx_phy_txc43128_ops = {
txc43128_prop_get, /* epo_prop_get */
txc43128_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_TXC43128 */
#if EFSYS_OPT_PHY_SFT9001
-static efx_phy_ops_t __cs __efx_phy_sft9001_ops = {
+static efx_phy_ops_t __efx_phy_sft9001_ops = {
NULL, /* epo_power */
sft9001_reset, /* epo_reset */
sft9001_reconfigure, /* epo_reconfigure */
@@ -194,16 +203,17 @@ static efx_phy_ops_t __cs __efx_phy_sft9001_ops = {
sft9001_prop_get, /* epo_prop_get */
sft9001_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
sft9001_bist_start, /* epo_bist_start */
sft9001_bist_poll, /* epo_bist_poll */
sft9001_bist_stop, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_SFT9001 */
#if EFSYS_OPT_PHY_QT2025C
-static efx_phy_ops_t __cs __efx_phy_qt2025c_ops = {
+static efx_phy_ops_t __efx_phy_qt2025c_ops = {
NULL, /* epo_power */
qt2025c_reset, /* epo_reset */
qt2025c_reconfigure, /* epo_reconfigure */
@@ -221,16 +231,17 @@ static efx_phy_ops_t __cs __efx_phy_qt2025c_ops = {
qt2025c_prop_get, /* epo_prop_get */
qt2025c_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_QT2025C */
#if EFSYS_OPT_SIENA
-static efx_phy_ops_t __cs __efx_phy_siena_ops = {
+static efx_phy_ops_t __efx_phy_siena_ops = {
siena_phy_power, /* epo_power */
NULL, /* epo_reset */
siena_phy_reconfigure, /* epo_reconfigure */
@@ -248,14 +259,43 @@ static efx_phy_ops_t __cs __efx_phy_siena_ops = {
siena_phy_prop_get, /* epo_prop_get */
siena_phy_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
siena_phy_bist_start, /* epo_bist_start */
siena_phy_bist_poll, /* epo_bist_poll */
siena_phy_bist_stop, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+static efx_phy_ops_t __efx_phy_hunt_ops = {
+ hunt_phy_power, /* epo_power */
+ NULL, /* epo_reset */
+ hunt_phy_reconfigure, /* epo_reconfigure */
+ hunt_phy_verify, /* epo_verify */
+ NULL, /* epo_uplink_check */
+ NULL, /* epo_downlink_check */
+ hunt_phy_oui_get, /* epo_oui_get */
+#if EFSYS_OPT_PHY_STATS
+ hunt_phy_stats_update, /* epo_stats_update */
+#endif /* EFSYS_OPT_PHY_STATS */
+#if EFSYS_OPT_PHY_PROPS
+#if EFSYS_OPT_NAMES
+ hunt_phy_prop_name, /* epo_prop_name */
+#endif
+ hunt_phy_prop_get, /* epo_prop_get */
+ hunt_phy_prop_set, /* epo_prop_set */
+#endif /* EFSYS_OPT_PHY_PROPS */
+#if EFSYS_OPT_BIST
+ hunt_bist_enable_offline, /* epo_bist_enable_offline */
+ hunt_bist_start, /* epo_bist_start */
+ hunt_bist_poll, /* epo_bist_poll */
+ hunt_bist_stop, /* epo_bist_stop */
+#endif /* EFSYS_OPT_BIST */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_phy_probe(
__in efx_nic_t *enp)
@@ -317,6 +357,11 @@ efx_phy_probe(
epop = (efx_phy_ops_t *)&__efx_phy_siena_ops;
break;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ epop = (efx_phy_ops_t *)&__efx_phy_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
default:
rc = ENOTSUP;
goto fail1;
@@ -516,8 +561,8 @@ efx_phy_media_type_get(
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */
-static const char __cs * __cs __efx_phy_stat_name[] = {
+/* START MKCONFIG GENERATED PhyStatNamesBlock d5f79b4bc2c050fe */
+static const char *__efx_phy_stat_name[] = {
"oui",
"pma_pmd_link_up",
"pma_pmd_rx_fault",
@@ -568,7 +613,7 @@ static const char __cs * __cs __efx_phy_stat_name[] = {
/* END MKCONFIG GENERATED PhyStatNamesBlock */
- const char __cs *
+ const char *
efx_phy_stat_name(
__in efx_nic_t *enp,
__in efx_phy_stat_t type)
@@ -602,7 +647,7 @@ efx_phy_stats_update(
#if EFSYS_OPT_PHY_PROPS
#if EFSYS_OPT_NAMES
- const char __cs *
+ const char *
efx_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -649,23 +694,51 @@ efx_phy_prop_set(
}
#endif /* EFSYS_OPT_PHY_STATS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+
+ __checkReturn int
+efx_bist_enable_offline(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_phy_ops_t *epop = epp->ep_epop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+ if (epop->epo_bist_enable_offline == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
__checkReturn int
-efx_phy_bist_start(
+efx_bist_start(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type)
+ __in efx_bist_type_t type)
{
efx_port_t *epp = &(enp->en_port);
efx_phy_ops_t *epop = epp->ep_epop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
- EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
- EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN);
+ EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+ EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
+ EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
if (epop->epo_bist_start == NULL) {
rc = ENOTSUP;
@@ -688,10 +761,10 @@ fail1:
}
__checkReturn int
-efx_phy_bist_poll(
+efx_bist_poll(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type,
- __out efx_phy_bist_result_t *resultp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
__out_opt uint32_t *value_maskp,
__out_ecount_opt(count) unsigned long *valuesp,
__in size_t count)
@@ -701,10 +774,9 @@ efx_phy_bist_poll(
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
- EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
+ EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+ EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
EFSYS_ASSERT(epop->epo_bist_poll != NULL);
@@ -728,18 +800,17 @@ fail1:
}
void
-efx_phy_bist_stop(
+efx_bist_stop(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type)
+ __in efx_bist_type_t type)
{
efx_port_t *epp = &(enp->en_port);
efx_phy_ops_t *epop = epp->ep_epop;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
- EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
+ EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+ EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
EFSYS_ASSERT(epop->epo_bist_stop != NULL);
@@ -747,10 +818,10 @@ efx_phy_bist_stop(
if (epop->epo_bist_stop != NULL)
epop->epo_bist_stop(enp, type);
- epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN;
+ epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
}
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
void
efx_phy_unprobe(
__in efx_nic_t *enp)
diff --git a/sys/dev/sfxge/common/efx_phy_ids.h b/sys/dev/sfxge/common/efx_phy_ids.h
new file mode 100644
index 000000000000..e06251923938
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_phy_ids.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2013-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_EFX_PHY_IDS_H
+#define _SYS_EFX_PHY_IDS_H
+
+#define EFX_PHY_NULL 0
+
+typedef enum efx_phy_type_e { /* GENERATED BY scripts/genfwdef */
+ EFX_PHY_TXC43128 = 1,
+ EFX_PHY_SFX7101 = 3,
+ EFX_PHY_QT2022C2 = 4,
+ EFX_PHY_PM8358 = 6,
+ EFX_PHY_SFT9001A = 8,
+ EFX_PHY_QT2025C = 9,
+ EFX_PHY_SFT9001B = 10,
+ EFX_PHY_QLX111V = 12,
+ EFX_PHY_QT2025_KR = 17,
+ EFX_PHY_AEL3020 = 18,
+ EFX_PHY_XFI_FARMI = 19,
+} efx_phy_type_t;
+
+
+#endif /* _SYS_EFX_PHY_IDS_H */
diff --git a/sys/dev/sfxge/common/efx_port.c b/sys/dev/sfxge/common/efx_port.c
index 0b67d065f2fb..a750c15edb3b 100644
--- a/sys/dev/sfxge/common/efx_port.c
+++ b/sys/dev/sfxge/common/efx_port.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -61,6 +66,9 @@ efx_port_init(
epp->ep_emop->emo_reconfigure(enp);
+ /* Pick up current phy capababilities */
+ efx_port_poll(enp, NULL);
+
/*
* Turn on the PHY if available, otherwise reset it, and
* reconfigure it with the current configuration.
@@ -96,7 +104,7 @@ fail1:
__checkReturn int
efx_port_poll(
__in efx_nic_t *enp,
- __out efx_link_mode_t *link_modep)
+ __out_opt efx_link_mode_t *link_modep)
{
efx_port_t *epp = &(enp->en_port);
efx_mac_ops_t *emop = epp->ep_emop;
@@ -141,7 +149,9 @@ efx_port_loopback_set(
EFSYS_ASSERT(emop != NULL);
EFSYS_ASSERT(link_mode < EFX_LINK_NMODES);
- if ((1 << loopback_type) & ~encp->enc_loopback_types[link_mode]) {
+
+ if (EFX_TEST_QWORD_BIT(encp->enc_loopback_types[link_mode],
+ loopback_type) == 0) {
rc = ENOTSUP;
goto fail1;
}
@@ -165,7 +175,7 @@ fail1:
#if EFSYS_OPT_NAMES
-static const char __cs * __cs __efx_loopback_type_name[] = {
+static const char *__efx_loopback_type_name[] = {
"OFF",
"DATA",
"GMAC",
@@ -184,13 +194,33 @@ static const char __cs * __cs __efx_loopback_type_name[] = {
"PHY_XS",
"PCS",
"PMA_PMD",
+ "XPORT",
+ "XGMII_WS",
+ "XAUI_WS",
+ "XAUI_WS_FAR",
+ "XAUI_WS_NEAR",
+ "GMII_WS",
+ "XFI_WS",
+ "XFI_WS_FAR",
+ "PHYXS_WS",
+ "PMA_INT",
+ "SD_NEAR",
+ "SD_FAR",
+ "PMA_INT_WS",
+ "SD_FEP2_WS",
+ "SD_FEP1_5_WS",
+ "SD_FEP_WS",
+ "SD_FES_WS",
};
- __checkReturn const char __cs *
+ __checkReturn const char *
efx_loopback_type_name(
__in efx_nic_t *enp,
__in efx_loopback_type_t type)
{
+ EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__efx_loopback_type_name) ==
+ EFX_LOOPBACK_NTYPES);
+
_NOTE(ARGUNUSED(enp))
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(type, <, EFX_LOOPBACK_NTYPES);
diff --git a/sys/dev/sfxge/common/efx_regs.h b/sys/dev/sfxge/common/efx_regs.h
index 4019663933cb..5ece431fe2ea 100644
--- a/sys/dev/sfxge/common/efx_regs.h
+++ b/sys/dev/sfxge/common/efx_regs.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -3854,7 +3859,7 @@ extern "C" {
*/
-#define FR_AZ_TX_PACE_TBL_OFST FR_BZ_TX_PACE_TBL_OFST
+#define FR_AZ_TX_PACE_TBL_OFST FR_BZ_TX_PACE_TBL_OFST
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/efx_regs_ef10.h b/sys/dev/sfxge/common/efx_regs_ef10.h
index c4a6d0e7c35b..8401726d6935 100644
--- a/sys/dev/sfxge/common/efx_regs_ef10.h
+++ b/sys/dev/sfxge/common/efx_regs_ef10.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2010 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -34,11 +39,13 @@ extern "C" {
/*
* BIU_HW_REV_ID_REG(32bit):
- *
+ *
*/
-#define ER_DZ_BIU_HW_REV_ID_REG 0x00000000
+#define ER_DZ_BIU_HW_REV_ID_REG_OFST 0x00000000
/* hunta0=pcie_pf_bar2 */
+#define ER_DZ_BIU_HW_REV_ID_REG_RESET 0xeb14face
+
#define ERF_DZ_HW_REV_ID_LBN 0
#define ERF_DZ_HW_REV_ID_WIDTH 32
@@ -46,13 +53,15 @@ extern "C" {
/*
* BIU_MC_SFT_STATUS_REG(32bit):
- *
+ *
*/
-#define ER_DZ_BIU_MC_SFT_STATUS_REG 0x00000010
+#define ER_DZ_BIU_MC_SFT_STATUS_REG_OFST 0x00000010
/* hunta0=pcie_pf_bar2 */
#define ER_DZ_BIU_MC_SFT_STATUS_REG_STEP 4
#define ER_DZ_BIU_MC_SFT_STATUS_REG_ROWS 8
+#define ER_DZ_BIU_MC_SFT_STATUS_REG_RESET 0x1111face
+
#define ERF_DZ_MC_SFT_STATUS_LBN 0
#define ERF_DZ_MC_SFT_STATUS_WIDTH 32
@@ -60,11 +69,13 @@ extern "C" {
/*
* BIU_INT_ISR_REG(32bit):
- *
+ *
*/
-#define ER_DZ_BIU_INT_ISR_REG 0x00000090
+#define ER_DZ_BIU_INT_ISR_REG_OFST 0x00000090
/* hunta0=pcie_pf_bar2 */
+#define ER_DZ_BIU_INT_ISR_REG_RESET 0x0
+
#define ERF_DZ_ISR_REG_LBN 0
#define ERF_DZ_ISR_REG_WIDTH 32
@@ -72,11 +83,13 @@ extern "C" {
/*
* MC_DB_LWRD_REG(32bit):
- *
+ *
*/
-#define ER_DZ_MC_DB_LWRD_REG 0x00000200
+#define ER_DZ_MC_DB_LWRD_REG_OFST 0x00000200
/* hunta0=pcie_pf_bar2 */
+#define ER_DZ_MC_DB_LWRD_REG_RESET 0x0
+
#define ERF_DZ_MC_DOORBELL_L_LBN 0
#define ERF_DZ_MC_DOORBELL_L_WIDTH 32
@@ -84,11 +97,13 @@ extern "C" {
/*
* MC_DB_HWRD_REG(32bit):
- *
+ *
*/
-#define ER_DZ_MC_DB_HWRD_REG 0x00000204
+#define ER_DZ_MC_DB_HWRD_REG_OFST 0x00000204
/* hunta0=pcie_pf_bar2 */
+#define ER_DZ_MC_DB_HWRD_REG_RESET 0x0
+
#define ERF_DZ_MC_DOORBELL_H_LBN 0
#define ERF_DZ_MC_DOORBELL_H_WIDTH 32
@@ -96,13 +111,15 @@ extern "C" {
/*
* EVQ_RPTR_REG(32bit):
- *
+ *
*/
-#define ER_DZ_EVQ_RPTR_REG 0x00000400
+#define ER_DZ_EVQ_RPTR_REG_OFST 0x00000400
/* hunta0=pcie_pf_bar2 */
-#define ER_DZ_EVQ_RPTR_REG_STEP 4096
+#define ER_DZ_EVQ_RPTR_REG_STEP 8192
#define ER_DZ_EVQ_RPTR_REG_ROWS 2048
+#define ER_DZ_EVQ_RPTR_REG_RESET 0x0
+
#define ERF_DZ_EVQ_RPTR_VLD_LBN 15
#define ERF_DZ_EVQ_RPTR_VLD_WIDTH 1
@@ -112,13 +129,15 @@ extern "C" {
/*
* EVQ_TMR_REG(32bit):
- *
+ *
*/
-#define ER_DZ_EVQ_TMR_REG 0x00000420
+#define ER_DZ_EVQ_TMR_REG_OFST 0x00000420
/* hunta0=pcie_pf_bar2 */
-#define ER_DZ_EVQ_TMR_REG_STEP 4096
+#define ER_DZ_EVQ_TMR_REG_STEP 8192
#define ER_DZ_EVQ_TMR_REG_ROWS 2048
+#define ER_DZ_EVQ_TMR_REG_RESET 0x0
+
#define ERF_DZ_TC_TIMER_MODE_LBN 14
#define ERF_DZ_TC_TIMER_MODE_WIDTH 2
@@ -128,28 +147,34 @@ extern "C" {
/*
* RX_DESC_UPD_REG(32bit):
- *
+ *
*/
-#define ER_DZ_RX_DESC_UPD_REG 0x00000830
+#define ER_DZ_RX_DESC_UPD_REG_OFST 0x00000830
/* hunta0=pcie_pf_bar2 */
-#define ER_DZ_RX_DESC_UPD_REG_STEP 4096
+#define ER_DZ_RX_DESC_UPD_REG_STEP 8192
#define ER_DZ_RX_DESC_UPD_REG_ROWS 2048
+#define ER_DZ_RX_DESC_UPD_REG_RESET 0x0
+
#define ERF_DZ_RX_DESC_WPTR_LBN 0
#define ERF_DZ_RX_DESC_WPTR_WIDTH 12
/*
- * TX_DESC_UPD_REG(76bit):
- *
+ * TX_DESC_UPD_REG(96bit):
+ *
*/
-#define ER_DZ_TX_DESC_UPD_REG 0x00000a10
+#define ER_DZ_TX_DESC_UPD_REG_OFST 0x00000a10
/* hunta0=pcie_pf_bar2 */
-#define ER_DZ_TX_DESC_UPD_REG_STEP 4096
+#define ER_DZ_TX_DESC_UPD_REG_STEP 8192
#define ER_DZ_TX_DESC_UPD_REG_ROWS 2048
+#define ER_DZ_TX_DESC_UPD_REG_RESET 0x0
+
+#define ERF_DZ_RSVD_LBN 76
+#define ERF_DZ_RSVD_WIDTH 20
#define ERF_DZ_TX_DESC_WPTR_LBN 64
#define ERF_DZ_TX_DESC_WPTR_WIDTH 12
#define ERF_DZ_TX_DESC_HWORD_LBN 32
@@ -157,14 +182,38 @@ extern "C" {
#define ERF_DZ_TX_DESC_LWORD_LBN 0
#define ERF_DZ_TX_DESC_LWORD_WIDTH 32
+/*
+ * The workaround for bug 35388 requires multiplexing writes through
+ * the ERF_DZ_TX_DESC_WPTR address.
+ * TX_DESC_UPD: 0ppppppppppp (bit 11 lost)
+ * EVQ_RPTR: 1000hhhhhhhh, 1001llllllll (split into high and low bits)
+ * EVQ_TMR: 11mmvvvvvvvv (bits 8:13 of value lost)
+ */
+#define ER_DD_EVQ_INDIRECT_OFST (ER_DZ_TX_DESC_UPD_REG_OFST + 2 * 4)
+#define ER_DD_EVQ_INDIRECT_STEP ER_DZ_TX_DESC_UPD_REG_STEP
+#define ERF_DD_EVQ_IND_RPTR_FLAGS_LBN 8
+#define ERF_DD_EVQ_IND_RPTR_FLAGS_WIDTH 4
+#define EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH 8
+#define EFE_DD_EVQ_IND_RPTR_FLAGS_LOW 9
+#define ERF_DD_EVQ_IND_RPTR_LBN 0
+#define ERF_DD_EVQ_IND_RPTR_WIDTH 8
+#define ERF_DD_EVQ_IND_TIMER_FLAGS_LBN 10
+#define ERF_DD_EVQ_IND_TIMER_FLAGS_WIDTH 2
+#define EFE_DD_EVQ_IND_TIMER_FLAGS 3
+#define ERF_DD_EVQ_IND_TIMER_MODE_LBN 8
+#define ERF_DD_EVQ_IND_TIMER_MODE_WIDTH 2
+#define ERF_DD_EVQ_IND_TIMER_VAL_LBN 0
+#define ERF_DD_EVQ_IND_TIMER_VAL_WIDTH 8
+
/* ES_DRIVER_EV */
#define ESF_DZ_DRV_CODE_LBN 60
#define ESF_DZ_DRV_CODE_WIDTH 4
#define ESF_DZ_DRV_SUB_CODE_LBN 56
#define ESF_DZ_DRV_SUB_CODE_WIDTH 4
-#define ESE_DZ_DRV_TIMER_EV 10
-#define ESE_DZ_DRV_WAKE_UP_EV 6
+#define ESE_DZ_DRV_TIMER_EV 3
+#define ESE_DZ_DRV_START_UP_EV 2
+#define ESE_DZ_DRV_WAKE_UP_EV 1
#define ESF_DZ_DRV_SUB_DATA_DW0_LBN 0
#define ESF_DZ_DRV_SUB_DATA_DW0_WIDTH 32
#define ESF_DZ_DRV_SUB_DATA_DW1_LBN 32
@@ -194,9 +243,9 @@ extern "C" {
/* ES_FF_UMSG_CPU2DL_DESC_FETCH */
-#define ESF_DZ_C2DDF_DSCR_CACHE_RPTR_LBN 112
+#define ESF_DZ_C2DDF_DSCR_CACHE_RPTR_LBN 208
#define ESF_DZ_C2DDF_DSCR_CACHE_RPTR_WIDTH 6
-#define ESF_DZ_C2DDF_QID_LBN 96
+#define ESF_DZ_C2DDF_QID_LBN 160
#define ESF_DZ_C2DDF_QID_WIDTH 11
#define ESF_DZ_C2DDF_DSCR_BASE_PAGE_ID_LBN 64
#define ESF_DZ_C2DDF_DSCR_BASE_PAGE_ID_WIDTH 18
@@ -217,16 +266,16 @@ extern "C" {
/* ES_FF_UMSG_CPU2DL_DESC_PUSH */
+#define ESF_DZ_C2DDP_DSCR_HW_RPTR_LBN 224
+#define ESF_DZ_C2DDP_DSCR_HW_RPTR_WIDTH 12
#define ESF_DZ_C2DDP_DESC_DW0_LBN 128
#define ESF_DZ_C2DDP_DESC_DW0_WIDTH 32
#define ESF_DZ_C2DDP_DESC_DW1_LBN 160
#define ESF_DZ_C2DDP_DESC_DW1_WIDTH 32
#define ESF_DZ_C2DDP_DESC_LBN 128
#define ESF_DZ_C2DDP_DESC_WIDTH 64
-#define ESF_DZ_C2DDP_QID_LBN 96
+#define ESF_DZ_C2DDP_QID_LBN 64
#define ESF_DZ_C2DDP_QID_WIDTH 11
-#define ESF_DZ_C2DDP_DSCR_HW_RPTR_LBN 48
-#define ESF_DZ_C2DDP_DSCR_HW_RPTR_WIDTH 12
#define ESF_DZ_C2DDP_DSCR_HW_WPTR_LBN 32
#define ESF_DZ_C2DDP_DSCR_HW_WPTR_WIDTH 12
#define ESF_DZ_C2DDP_OID_LBN 16
@@ -258,8 +307,18 @@ extern "C" {
/* ES_FF_UMSG_CPU2EV_TXCMPLT */
-#define ESF_DZ_C2ET_EV_SOFT0_LBN 32
-#define ESF_DZ_C2ET_EV_SOFT0_WIDTH 16
+#define ESF_DZ_C2ET_EV_SOFT2_LBN 48
+#define ESF_DZ_C2ET_EV_SOFT2_WIDTH 16
+#define ESF_DZ_C2ET_EV_CODE_LBN 42
+#define ESF_DZ_C2ET_EV_CODE_WIDTH 4
+#define ESF_DZ_C2ET_EV_OVERRIDE_HOLDOFF_LBN 41
+#define ESF_DZ_C2ET_EV_OVERRIDE_HOLDOFF_WIDTH 1
+#define ESF_DZ_C2ET_EV_DROP_EVENT_LBN 40
+#define ESF_DZ_C2ET_EV_DROP_EVENT_WIDTH 1
+#define ESF_DZ_C2ET_EV_CAN_MERGE_LBN 39
+#define ESF_DZ_C2ET_EV_CAN_MERGE_WIDTH 1
+#define ESF_DZ_C2ET_EV_SOFT1_LBN 32
+#define ESF_DZ_C2ET_EV_SOFT1_WIDTH 7
#define ESF_DZ_C2ET_DSCR_IDX_LBN 16
#define ESF_DZ_C2ET_DSCR_IDX_WIDTH 16
#define ESF_DZ_C2ET_EV_QID_LBN 5
@@ -310,7 +369,6 @@ extern "C" {
#define ESF_DZ_C2RIP_EV_ARG1_WIDTH 16
#define ESF_DZ_C2RIP_UPD_CRC_MODE_LBN 157
#define ESF_DZ_C2RIP_UPD_CRC_MODE_WIDTH 3
-#define ESE_DZ_C2RIP_FCOIP_MPA 5
#define ESE_DZ_C2RIP_FCOIP_FCOE 4
#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3
#define ESE_DZ_C2RIP_ISCSI_HDR 2
@@ -379,7 +437,7 @@ extern "C" {
#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_DW1_WIDTH 16
#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_LBN 64
#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_WIDTH 48
-#define ESF_DZ_C2SD_OFFSET_LBN 48
+#define ESF_DZ_C2SD_OFFSET_LBN 80
#define ESF_DZ_C2SD_OFFSET_WIDTH 8
#define ESF_DZ_C2SD_QID_LBN 32
#define ESF_DZ_C2SD_QID_WIDTH 11
@@ -419,7 +477,6 @@ extern "C" {
#define ESF_DZ_C2TDB_DESC_IDX_WIDTH 16
#define ESF_DZ_C2TDB_UPD_CRC_MODE_LBN 93
#define ESF_DZ_C2TDB_UPD_CRC_MODE_WIDTH 3
-#define ESE_DZ_C2RIP_FCOIP_MPA 5
#define ESE_DZ_C2RIP_FCOIP_FCOE 4
#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3
#define ESE_DZ_C2RIP_ISCSI_HDR 2
@@ -460,6 +517,14 @@ extern "C" {
/* ES_FF_UMSG_CPU2TXDP_EGR */
+#define ESF_DZ_C2TE_RMON_SOFT_LBN 240
+#define ESF_DZ_C2TE_RMON_SOFT_WIDTH 1
+#define ESF_DZ_C2TE_VLAN_PRIO_LBN 224
+#define ESF_DZ_C2TE_VLAN_PRIO_WIDTH 3
+#define ESF_DZ_C2TE_VLAN_LBN 208
+#define ESF_DZ_C2TE_VLAN_WIDTH 1
+#define ESF_DZ_C2TE_QID_LBN 192
+#define ESF_DZ_C2TE_QID_WIDTH 11
#define ESF_DZ_C2TE_PEDIT_DELTA_LBN 168
#define ESF_DZ_C2TE_PEDIT_DELTA_WIDTH 8
#define ESF_DZ_C2TE_PYLOAD_OFST_LBN 160
@@ -480,20 +545,19 @@ extern "C" {
#define ESF_DZ_C2TE_IS_FCOE_WIDTH 1
#define ESF_DZ_C2TE_PARSE_INCOMP_LBN 128
#define ESF_DZ_C2TE_PARSE_INCOMP_WIDTH 1
-#define ESF_DZ_C2TE_PKT_LEN_LBN 112
-#define ESF_DZ_C2TE_PKT_LEN_WIDTH 16
-#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_LBN 97
-#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_WIDTH 1
-#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_LBN 96
-#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_WIDTH 1
-#define ESF_DZ_C2TE_UPD_CRC_MODE_LBN 93
+#define ESF_DZ_C2TE_UPD_CRC_MODE_LBN 98
#define ESF_DZ_C2TE_UPD_CRC_MODE_WIDTH 3
-#define ESE_DZ_C2RIP_FCOIP_MPA 5
#define ESE_DZ_C2RIP_FCOIP_FCOE 4
#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3
#define ESE_DZ_C2RIP_ISCSI_HDR 2
#define ESE_DZ_C2RIP_FCOE 1
#define ESE_DZ_C2RIP_OFF 0
+#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_LBN 97
+#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_WIDTH 1
+#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_LBN 96
+#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_WIDTH 1
+#define ESF_DZ_C2TE_PKT_LEN_LBN 64
+#define ESF_DZ_C2TE_PKT_LEN_WIDTH 16
#define ESF_DZ_C2TE_FINFO_WRD3_LBN 48
#define ESF_DZ_C2TE_FINFO_WRD3_WIDTH 16
#define ESF_DZ_C2TE_FINFO_WRD2_LBN 32
@@ -542,7 +606,7 @@ extern "C" {
/* ES_FF_UMSG_PACER_BKT_TBL_RD_REQ */
#define ESF_DZ_BKT_ID_LBN 0
-#define ESF_DZ_BKT_ID_WIDTH 9
+#define ESF_DZ_BKT_ID_WIDTH 10
/* ES_FF_UMSG_PACER_BKT_TBL_RD_RSP */
@@ -563,7 +627,7 @@ extern "C" {
#define ESF_DZ_MAX_FILL_REG_LBN 12
#define ESF_DZ_MAX_FILL_REG_WIDTH 2
#define ESF_DZ_BKT_ID_LBN 0
-#define ESF_DZ_BKT_ID_WIDTH 9
+#define ESF_DZ_BKT_ID_WIDTH 10
/* ES_FF_UMSG_PACER_BKT_TBL_WR_REQ */
@@ -580,7 +644,7 @@ extern "C" {
#define ESF_DZ_MAX_FILL_REG_LBN 12
#define ESF_DZ_MAX_FILL_REG_WIDTH 2
#define ESF_DZ_BKT_ID_LBN 0
-#define ESF_DZ_BKT_ID_WIDTH 9
+#define ESF_DZ_BKT_ID_WIDTH 10
/* ES_FF_UMSG_PACER_TXQ_TBL_RD_REQ */
@@ -590,13 +654,13 @@ extern "C" {
/* ES_FF_UMSG_PACER_TXQ_TBL_RD_RSP */
#define ESF_DZ_MAX_BKT2_LBN 112
-#define ESF_DZ_MAX_BKT2_WIDTH 9
+#define ESF_DZ_MAX_BKT2_WIDTH 10
#define ESF_DZ_MAX_BKT1_LBN 96
-#define ESF_DZ_MAX_BKT1_WIDTH 9
+#define ESF_DZ_MAX_BKT1_WIDTH 10
#define ESF_DZ_MAX_BKT0_LBN 80
-#define ESF_DZ_MAX_BKT0_WIDTH 9
+#define ESF_DZ_MAX_BKT0_WIDTH 10
#define ESF_DZ_MIN_BKT_LBN 64
-#define ESF_DZ_MIN_BKT_WIDTH 9
+#define ESF_DZ_MIN_BKT_WIDTH 10
#define ESF_DZ_LABEL_LBN 48
#define ESF_DZ_LABEL_WIDTH 4
#define ESF_DZ_PQ_FLAGS_LBN 32
@@ -609,13 +673,13 @@ extern "C" {
/* ES_FF_UMSG_PACER_TXQ_TBL_WR_REQ */
#define ESF_DZ_MAX_BKT2_LBN 112
-#define ESF_DZ_MAX_BKT2_WIDTH 9
+#define ESF_DZ_MAX_BKT2_WIDTH 10
#define ESF_DZ_MAX_BKT1_LBN 96
-#define ESF_DZ_MAX_BKT1_WIDTH 9
+#define ESF_DZ_MAX_BKT1_WIDTH 10
#define ESF_DZ_MAX_BKT0_LBN 80
-#define ESF_DZ_MAX_BKT0_WIDTH 9
+#define ESF_DZ_MAX_BKT0_WIDTH 10
#define ESF_DZ_MIN_BKT_LBN 64
-#define ESF_DZ_MIN_BKT_WIDTH 9
+#define ESF_DZ_MIN_BKT_WIDTH 10
#define ESF_DZ_LABEL_LBN 48
#define ESF_DZ_LABEL_WIDTH 4
#define ESF_DZ_PQ_FLAGS_LBN 32
@@ -663,17 +727,19 @@ extern "C" {
/* ES_FF_UMSG_RXDP_INGR2CPU */
+#define ESF_DZ_RI2C_QUEUE_ID_LBN 224
+#define ESF_DZ_RI2C_QUEUE_ID_WIDTH 11
#define ESF_DZ_RI2C_LEN_LBN 208
#define ESF_DZ_RI2C_LEN_WIDTH 16
-#define ESF_DZ_RI2C_L4_CLASS_LBN 202
+#define ESF_DZ_RI2C_L4_CLASS_LBN 205
#define ESF_DZ_RI2C_L4_CLASS_WIDTH 3
-#define ESF_DZ_RI2C_L3_CLASS_LBN 199
+#define ESF_DZ_RI2C_L3_CLASS_LBN 202
#define ESF_DZ_RI2C_L3_CLASS_WIDTH 3
-#define ESF_DZ_RI2C_ETHTAG_CLASS_LBN 196
+#define ESF_DZ_RI2C_ETHTAG_CLASS_LBN 199
#define ESF_DZ_RI2C_ETHTAG_CLASS_WIDTH 3
-#define ESF_DZ_RI2C_ETHBASE_CLASS_LBN 193
+#define ESF_DZ_RI2C_ETHBASE_CLASS_LBN 196
#define ESF_DZ_RI2C_ETHBASE_CLASS_WIDTH 3
-#define ESF_DZ_RI2C_MAC_CLASS_LBN 192
+#define ESF_DZ_RI2C_MAC_CLASS_LBN 195
#define ESF_DZ_RI2C_MAC_CLASS_WIDTH 1
#define ESF_DZ_RI2C_PKT_OFST_LBN 176
#define ESF_DZ_RI2C_PKT_OFST_WIDTH 16
@@ -765,12 +831,12 @@ extern "C" {
#define ESF_DZ_TD2CP_ETHBASE_CLASS_WIDTH 3
#define ESF_DZ_TD2CP_MAC_CLASS_LBN 240
#define ESF_DZ_TD2CP_MAC_CLASS_WIDTH 1
-#define ESF_DZ_TD2CP_SOFT_LBN 226
-#define ESF_DZ_TD2CP_SOFT_WIDTH 14
-#define ESF_DZ_TD2CP_PKT_ABORT_LBN 225
+#define ESF_DZ_TD2CP_PCIE_ERR_OR_ABORT_LBN 239
+#define ESF_DZ_TD2CP_PCIE_ERR_OR_ABORT_WIDTH 1
+#define ESF_DZ_TD2CP_PKT_ABORT_LBN 238
#define ESF_DZ_TD2CP_PKT_ABORT_WIDTH 1
-#define ESF_DZ_TD2CP_PCIE_ERR_LBN 224
-#define ESF_DZ_TD2CP_PCIE_ERR_WIDTH 1
+#define ESF_DZ_TD2CP_SOFT_LBN 224
+#define ESF_DZ_TD2CP_SOFT_WIDTH 14
#define ESF_DZ_TD2CP_DESC_IDX_LBN 208
#define ESF_DZ_TD2CP_DESC_IDX_WIDTH 16
#define ESF_DZ_TD2CP_PKT_LEN_LBN 192
@@ -854,7 +920,7 @@ extern "C" {
/* ES_LUE_DB_MATCH_ENTRY */
#define ESF_DZ_LUE_DSCRMNTR_LBN 140
-#define ESF_DZ_LUE_DSCRMNTR_WIDTH 4
+#define ESF_DZ_LUE_DSCRMNTR_WIDTH 6
#define ESF_DZ_LUE_MATCH_VAL_DW0_LBN 44
#define ESF_DZ_LUE_MATCH_VAL_DW0_WIDTH 32
#define ESF_DZ_LUE_MATCH_VAL_DW1_LBN 76
@@ -875,13 +941,11 @@ extern "C" {
#define ESE_DZ_LUE_SINGLE 0
#define ESF_DZ_LUE_RCPNTR_LBN 0
#define ESF_DZ_LUE_RCPNTR_WIDTH 24
-#define ESF_DZ_LUE_RCPNTR_ME_PTR_LBN 0
-#define ESF_DZ_LUE_RCPNTR_ME_PTR_WIDTH 14
/* ES_LUE_DB_NONMATCH_ENTRY */
#define ESF_DZ_LUE_DSCRMNTR_LBN 140
-#define ESF_DZ_LUE_DSCRMNTR_WIDTH 4
+#define ESF_DZ_LUE_DSCRMNTR_WIDTH 6
#define ESF_DZ_LUE_TERMINAL_LBN 139
#define ESF_DZ_LUE_TERMINAL_WIDTH 1
#define ESF_DZ_LUE_LAST_LBN 138
@@ -914,9 +978,9 @@ extern "C" {
#define ESF_DZ_MC2L_DR_PAD_DW3_LBN 118
#define ESF_DZ_MC2L_DR_PAD_DW3_WIDTH 32
#define ESF_DZ_MC2L_DR_PAD_DW4_LBN 150
-#define ESF_DZ_MC2L_DR_PAD_DW4_WIDTH 16
+#define ESF_DZ_MC2L_DR_PAD_DW4_WIDTH 18
#define ESF_DZ_MC2L_DR_PAD_LBN 22
-#define ESF_DZ_MC2L_DR_PAD_WIDTH 144
+#define ESF_DZ_MC2L_DR_PAD_WIDTH 146
#define ESF_DZ_MC2L_DR_ADDR_LBN 8
#define ESF_DZ_MC2L_DR_ADDR_WIDTH 14
#define ESF_DZ_MC2L_DR_THREAD_ID_LBN 5
@@ -933,7 +997,7 @@ extern "C" {
/* ES_LUE_MC_DIRECT_RESPONSE_MSG */
#define ESF_DZ_L2MC_DR_PAD_LBN 146
-#define ESF_DZ_L2MC_DR_PAD_WIDTH 6
+#define ESF_DZ_L2MC_DR_PAD_WIDTH 8
#define ESF_DZ_L2MC_DR_RCPNT_PTR_LBN 132
#define ESF_DZ_L2MC_DR_RCPNT_PTR_WIDTH 14
#define ESF_DZ_L2MC_DR_RCPNT4_LBN 108
@@ -972,9 +1036,9 @@ extern "C" {
#define ESF_DZ_MC2L_GPR_PAD_DW3_LBN 118
#define ESF_DZ_MC2L_GPR_PAD_DW3_WIDTH 32
#define ESF_DZ_MC2L_GPR_PAD_DW4_LBN 150
-#define ESF_DZ_MC2L_GPR_PAD_DW4_WIDTH 16
+#define ESF_DZ_MC2L_GPR_PAD_DW4_WIDTH 18
#define ESF_DZ_MC2L_GPR_PAD_LBN 22
-#define ESF_DZ_MC2L_GPR_PAD_WIDTH 144
+#define ESF_DZ_MC2L_GPR_PAD_WIDTH 146
#define ESF_DZ_MC2L_GPR_ADDR_LBN 8
#define ESF_DZ_MC2L_GPR_ADDR_WIDTH 14
#define ESF_DZ_MC2L_GPR_THREAD_ID_LBN 5
@@ -999,9 +1063,9 @@ extern "C" {
#define ESF_DZ_L2MC_GPR_DATA_DW3_LBN 104
#define ESF_DZ_L2MC_GPR_DATA_DW3_WIDTH 32
#define ESF_DZ_L2MC_GPR_DATA_DW4_LBN 136
-#define ESF_DZ_L2MC_GPR_DATA_DW4_WIDTH 16
+#define ESF_DZ_L2MC_GPR_DATA_DW4_WIDTH 18
#define ESF_DZ_L2MC_GPR_DATA_LBN 8
-#define ESF_DZ_L2MC_GPR_DATA_WIDTH 144
+#define ESF_DZ_L2MC_GPR_DATA_WIDTH 146
#define ESF_DZ_L2MC_GPR_THREAD_ID_LBN 5
#define ESF_DZ_L2MC_GPR_THREAD_ID_WIDTH 3
#define ESF_DZ_L2MC_GPR_CLIENT_ID_LBN 2
@@ -1024,9 +1088,9 @@ extern "C" {
#define ESF_DZ_MC2L_GPW_DATA_DW3_LBN 118
#define ESF_DZ_MC2L_GPW_DATA_DW3_WIDTH 32
#define ESF_DZ_MC2L_GPW_DATA_DW4_LBN 150
-#define ESF_DZ_MC2L_GPW_DATA_DW4_WIDTH 16
+#define ESF_DZ_MC2L_GPW_DATA_DW4_WIDTH 18
#define ESF_DZ_MC2L_GPW_DATA_LBN 22
-#define ESF_DZ_MC2L_GPW_DATA_WIDTH 144
+#define ESF_DZ_MC2L_GPW_DATA_WIDTH 146
#define ESF_DZ_MC2L_GPW_ADDR_LBN 8
#define ESF_DZ_MC2L_GPW_ADDR_WIDTH 14
#define ESF_DZ_MC2L_GPW_THREAD_ID_LBN 5
@@ -1042,22 +1106,22 @@ extern "C" {
/* ES_LUE_MC_MATCH_REQUEST_MSG */
-#define ESF_DZ_MC2L_MR_PAD_LBN 135
+#define ESF_DZ_MC2L_MR_PAD_LBN 137
#define ESF_DZ_MC2L_MR_PAD_WIDTH 31
-#define ESF_DZ_MC2L_MR_HASH2_LBN 122
+#define ESF_DZ_MC2L_MR_HASH2_LBN 124
#define ESF_DZ_MC2L_MR_HASH2_WIDTH 13
-#define ESF_DZ_MC2L_MR_HASH1_LBN 108
+#define ESF_DZ_MC2L_MR_HASH1_LBN 110
#define ESF_DZ_MC2L_MR_HASH1_WIDTH 14
-#define ESF_DZ_MC2L_MR_MATCH_BITS_DW0_LBN 12
+#define ESF_DZ_MC2L_MR_MATCH_BITS_DW0_LBN 14
#define ESF_DZ_MC2L_MR_MATCH_BITS_DW0_WIDTH 32
-#define ESF_DZ_MC2L_MR_MATCH_BITS_DW1_LBN 44
+#define ESF_DZ_MC2L_MR_MATCH_BITS_DW1_LBN 46
#define ESF_DZ_MC2L_MR_MATCH_BITS_DW1_WIDTH 32
-#define ESF_DZ_MC2L_MR_MATCH_BITS_DW2_LBN 76
+#define ESF_DZ_MC2L_MR_MATCH_BITS_DW2_LBN 78
#define ESF_DZ_MC2L_MR_MATCH_BITS_DW2_WIDTH 32
-#define ESF_DZ_MC2L_MR_MATCH_BITS_LBN 12
+#define ESF_DZ_MC2L_MR_MATCH_BITS_LBN 14
#define ESF_DZ_MC2L_MR_MATCH_BITS_WIDTH 96
#define ESF_DZ_MC2L_MR_DSCRMNTR_LBN 8
-#define ESF_DZ_MC2L_MR_DSCRMNTR_WIDTH 4
+#define ESF_DZ_MC2L_MR_DSCRMNTR_WIDTH 6
#define ESF_DZ_MC2L_MR_THREAD_ID_LBN 5
#define ESF_DZ_MC2L_MR_THREAD_ID_WIDTH 3
#define ESF_DZ_MC2L_MR_CLIENT_ID_LBN 2
@@ -1078,9 +1142,9 @@ extern "C" {
#define ESF_DZ_L2MC_MR_PAD_DW2_LBN 117
#define ESF_DZ_L2MC_MR_PAD_DW2_WIDTH 32
#define ESF_DZ_L2MC_MR_PAD_DW3_LBN 149
-#define ESF_DZ_L2MC_MR_PAD_DW3_WIDTH 3
+#define ESF_DZ_L2MC_MR_PAD_DW3_WIDTH 5
#define ESF_DZ_L2MC_MR_PAD_LBN 53
-#define ESF_DZ_L2MC_MR_PAD_WIDTH 99
+#define ESF_DZ_L2MC_MR_PAD_WIDTH 101
#define ESF_DZ_L2MC_MR_LUE_RCPNT_LBN 29
#define ESF_DZ_L2MC_MR_LUE_RCPNT_WIDTH 24
#define ESF_DZ_L2MC_MR_RX_MCAST_LBN 28
@@ -1115,9 +1179,9 @@ extern "C" {
#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW3_LBN 104
#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW3_WIDTH 32
#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW4_LBN 136
-#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW4_WIDTH 30
+#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW4_WIDTH 32
#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_LBN 8
-#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_WIDTH 158
+#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_WIDTH 160
#define ESF_DZ_LUE_HW_REQ_BASE_THREAD_ID_LBN 5
#define ESF_DZ_LUE_HW_REQ_BASE_THREAD_ID_WIDTH 3
#define ESF_DZ_LUE_HW_REQ_BASE_CLIENT_ID_LBN 2
@@ -1144,9 +1208,9 @@ extern "C" {
#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW3_LBN 104
#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW3_WIDTH 32
#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW4_LBN 136
-#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW4_WIDTH 16
+#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW4_WIDTH 18
#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_LBN 8
-#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_WIDTH 144
+#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_WIDTH 146
#define ESF_DZ_LUE_HW_RSP_BASE_THREAD_ID_LBN 5
#define ESF_DZ_LUE_HW_RSP_BASE_THREAD_ID_WIDTH 3
#define ESF_DZ_LUE_HW_RSP_BASE_CLIENT_ID_LBN 2
@@ -1244,9 +1308,9 @@ extern "C" {
#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW3_LBN 104
#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW3_WIDTH 32
#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW4_LBN 136
-#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW4_WIDTH 16
+#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW4_WIDTH 18
#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_LBN 8
-#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_WIDTH 144
+#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_WIDTH 146
#define ESF_DZ_LUE_HW_RSP_GPRD_THREAD_ID_LBN 5
#define ESF_DZ_LUE_HW_RSP_GPRD_THREAD_ID_WIDTH 3
#define ESF_DZ_LUE_HW_RSP_GPRD_CLIENT_ID_LBN 2
@@ -1273,9 +1337,9 @@ extern "C" {
#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW3_LBN 118
#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW3_WIDTH 32
#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW4_LBN 150
-#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW4_WIDTH 16
+#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW4_WIDTH 18
#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_LBN 22
-#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_WIDTH 144
+#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_WIDTH 146
#define ESF_DZ_LUE_HW_REQ_GPWR_ADDR_LBN 8
#define ESF_DZ_LUE_HW_REQ_GPWR_ADDR_WIDTH 14
#define ESF_DZ_LUE_HW_REQ_GPWR_THREAD_ID_LBN 5
@@ -1295,22 +1359,22 @@ extern "C" {
/* ES_LUE_MSG_MATCH_REQ */
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_LBN 135
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_WIDTH 6
-#define ESF_DZ_LUE_HW_REQ_MATCH_HASH2_LBN 122
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_LBN 137
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_WIDTH 8
+#define ESF_DZ_LUE_HW_REQ_MATCH_HASH2_LBN 124
#define ESF_DZ_LUE_HW_REQ_MATCH_HASH2_WIDTH 13
-#define ESF_DZ_LUE_HW_REQ_MATCH_HASH1_LBN 108
+#define ESF_DZ_LUE_HW_REQ_MATCH_HASH1_LBN 110
#define ESF_DZ_LUE_HW_REQ_MATCH_HASH1_WIDTH 14
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW0_LBN 12
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW0_LBN 14
#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW0_WIDTH 32
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW1_LBN 44
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW1_LBN 46
#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW1_WIDTH 32
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW2_LBN 76
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW2_LBN 78
#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW2_WIDTH 32
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_LBN 12
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_LBN 14
#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_WIDTH 96
#define ESF_DZ_LUE_HW_REQ_MATCH_DSCRMNTR_LBN 8
-#define ESF_DZ_LUE_HW_REQ_MATCH_DSCRMNTR_WIDTH 4
+#define ESF_DZ_LUE_HW_REQ_MATCH_DSCRMNTR_WIDTH 6
#define ESF_DZ_LUE_HW_REQ_MATCH_THREAD_ID_LBN 5
#define ESF_DZ_LUE_HW_REQ_MATCH_THREAD_ID_WIDTH 3
#define ESF_DZ_LUE_HW_REQ_MATCH_CLIENT_ID_LBN 2
@@ -1543,10 +1607,10 @@ extern "C" {
#define ESF_DZ_RX_OVERRIDE_HOLDOFF_WIDTH 1
#define ESF_DZ_RX_DROP_EVENT_LBN 58
#define ESF_DZ_RX_DROP_EVENT_WIDTH 1
-#define ESF_DZ_RX_EV_RSVD2_LBN 55
-#define ESF_DZ_RX_EV_RSVD2_WIDTH 3
+#define ESF_DZ_RX_EV_RSVD2_LBN 54
+#define ESF_DZ_RX_EV_RSVD2_WIDTH 4
#define ESF_DZ_RX_EV_SOFT2_LBN 52
-#define ESF_DZ_RX_EV_SOFT2_WIDTH 3
+#define ESF_DZ_RX_EV_SOFT2_WIDTH 2
#define ESF_DZ_RX_DSC_PTR_LBITS_LBN 48
#define ESF_DZ_RX_DSC_PTR_LBITS_WIDTH 4
#define ESF_DZ_RX_L4_CLASS_LBN 45
@@ -1590,8 +1654,10 @@ extern "C" {
#define ESE_DZ_MAC_CLASS_UCAST 0
#define ESF_DZ_RX_EV_SOFT1_LBN 32
#define ESF_DZ_RX_EV_SOFT1_WIDTH 3
-#define ESF_DZ_RX_EV_RSVD1_LBN 30
-#define ESF_DZ_RX_EV_RSVD1_WIDTH 2
+#define ESF_DZ_RX_EV_RSVD1_LBN 31
+#define ESF_DZ_RX_EV_RSVD1_WIDTH 1
+#define ESF_DZ_RX_ABORT_LBN 30
+#define ESF_DZ_RX_ABORT_WIDTH 1
#define ESF_DZ_RX_ECC_ERR_LBN 29
#define ESF_DZ_RX_ECC_ERR_WIDTH 1
#define ESF_DZ_RX_CRC1_ERR_LBN 28
@@ -1605,7 +1671,7 @@ extern "C" {
#define ESF_DZ_RX_ECRC_ERR_LBN 24
#define ESF_DZ_RX_ECRC_ERR_WIDTH 1
#define ESF_DZ_RX_QLABEL_LBN 16
-#define ESF_DZ_RX_QLABEL_WIDTH 8
+#define ESF_DZ_RX_QLABEL_WIDTH 5
#define ESF_DZ_RX_PARSE_INCOMPLETE_LBN 15
#define ESF_DZ_RX_PARSE_INCOMPLETE_WIDTH 1
#define ESF_DZ_RX_CONT_LBN 14
@@ -1687,16 +1753,16 @@ extern "C" {
#define ESF_DZ_RX_U_FAST_PATH_WIDTH 1
#define ESF_DZ_RX_U_SOFT1_B1R0_4_LBN 68
#define ESF_DZ_RX_U_SOFT1_B1R0_4_WIDTH 1
-#define ESF_DZ_RX_U_NO_FLUSH_LBN 67
-#define ESF_DZ_RX_U_NO_FLUSH_WIDTH 1
+#define ESF_DZ_RX_U_CHAIN_LBN 67
+#define ESF_DZ_RX_U_CHAIN_WIDTH 1
#define ESF_DZ_RX_U_SOFT1_B1R0_3_LBN 67
#define ESF_DZ_RX_U_SOFT1_B1R0_3_WIDTH 1
#define ESF_DZ_RX_U_DESC_ACTIVE_LBN 66
#define ESF_DZ_RX_U_DESC_ACTIVE_WIDTH 1
#define ESF_DZ_RX_U_SOFT1_B1R0_2_LBN 66
#define ESF_DZ_RX_U_SOFT1_B1R0_2_WIDTH 1
-#define ESF_DZ_RX_U_HDR_SPLIT_LBN 65
-#define ESF_DZ_RX_U_HDR_SPLIT_WIDTH 1
+#define ESF_DZ_RX_U_TIMESTAMP_LBN 65
+#define ESF_DZ_RX_U_TIMESTAMP_WIDTH 1
#define ESF_DZ_RX_U_SOFT1_B1R0_1_LBN 65
#define ESF_DZ_RX_U_SOFT1_B1R0_1_WIDTH 1
#define ESF_DZ_RX_U_Q_ENABLE_LBN 64
@@ -1728,12 +1794,14 @@ extern "C" {
#define ESF_DZ_RX_U_DSCR_BASE_PAGE_ID_WIDTH 18
#define ESF_DZ_RX_U_SOFT18_B1R0_0_LBN 64
#define ESF_DZ_RX_U_SOFT18_B1R0_0_WIDTH 18
-#define ESF_DZ_RX_U_QST1_SPARE_LBN 52
-#define ESF_DZ_RX_U_QST1_SPARE_WIDTH 12
+#define ESF_DZ_RX_U_QST1_SPARE_LBN 53
+#define ESF_DZ_RX_U_QST1_SPARE_WIDTH 11
#define ESF_DZ_RX_U_SOFT16_B0R3_0_LBN 48
#define ESF_DZ_RX_U_SOFT16_B0R3_0_WIDTH 16
-#define ESF_DZ_RX_U_TIMESTAMP_LBN 51
-#define ESF_DZ_RX_U_TIMESTAMP_WIDTH 1
+#define ESF_DZ_RX_U_NO_FLUSH_LBN 52
+#define ESF_DZ_RX_U_NO_FLUSH_WIDTH 1
+#define ESF_DZ_RX_U_HDR_SPLIT_LBN 51
+#define ESF_DZ_RX_U_HDR_SPLIT_WIDTH 1
#define ESF_DZ_RX_U_DOORBELL_ENABLED_LBN 50
#define ESF_DZ_RX_U_DOORBELL_ENABLED_WIDTH 1
#define ESF_DZ_RX_U_WORK_PENDING_LBN 49
@@ -1758,6 +1826,39 @@ extern "C" {
#define ESF_DZ_RX_U_SOFT3_B0R0_0_WIDTH 3
+/* ES_SGMII_DEV_PTNR_ABILITY_1000BX_MD */
+#define ESF_DZ_SGMII_DPA_NXT_PG_LBN 15
+#define ESF_DZ_SGMII_DPA_NXT_PG_WIDTH 1
+#define ESF_DZ_SGMII_DPA_ACK_LBN 14
+#define ESF_DZ_SGMII_DPA_ACK_WIDTH 1
+#define ESF_DZ_SGMII_DPA_REMOTE_FLT_LBN 12
+#define ESF_DZ_SGMII_DPA_REMOTE_FLT_WIDTH 2
+#define ESE_DZ_SGMII_DPA_RF_AN_ERR 3
+#define ESE_DZ_SGMII_DPA_RF_OFFLINE 2
+#define ESE_DZ_SGMII_DPA_RF_LINK_FAIL 1
+#define ESE_DZ_SGMII_DPA_RF_NONE 0
+#define ESF_DZ_SGMII_DPA_PS_LBN 7
+#define ESF_DZ_SGMII_DPA_PS_WIDTH 2
+#define ESF_DZ_SGMII_DPA_HD_LBN 6
+#define ESF_DZ_SGMII_DPA_HD_WIDTH 1
+#define ESF_DZ_SGMII_DPA_FD_LBN 5
+#define ESF_DZ_SGMII_DPA_FD_WIDTH 1
+
+
+/* ES_SGMII_DEV_PTNR_ABILITY_SGMII_MD */
+#define ESF_DZ_SGMII_DPA_CPR_LINK_STATE_LBN 15
+#define ESF_DZ_SGMII_DPA_CPR_LINK_STATE_WIDTH 1
+#define ESF_DZ_SGMII_DPA_ACK_LBN 14
+#define ESF_DZ_SGMII_DPA_ACK_WIDTH 1
+#define ESF_DZ_SGMII_CPR_BPLX_STS_LBN 12
+#define ESF_DZ_SGMII_CPR_BPLX_STS_WIDTH 1
+#define ESF_DZ_SGMII_DPA_COPPER_SPEED_LBN 10
+#define ESF_DZ_SGMII_DPA_COPPER_SPEED_WIDTH 2
+#define ESE_DZ_SGMII_DPA_CPR_1GBS 2
+#define ESE_DZ_SGMII_DPA_CPR_100MBS 1
+#define ESE_DZ_SGMII_DPA_CPR_10MBS 0
+
+
/* ES_SMC_BUFTBL_CNTRL_ENTRY */
#define ESF_DZ_SMC_SW_CNTXT_DW0_LBN 16
#define ESF_DZ_SMC_SW_CNTXT_DW0_WIDTH 32
@@ -2187,6 +2288,30 @@ extern "C" {
#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0
+/* ES_TX_CSUM_TSTAMP_DESC */
+#define ESF_DZ_TX_DESC_IS_OPT_LBN 63
+#define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1
+#define ESF_DZ_TX_OPTION_TYPE_LBN 60
+#define ESF_DZ_TX_OPTION_TYPE_WIDTH 3
+#define ESE_DZ_TX_OPTION_DESC_TSO 7
+#define ESE_DZ_TX_OPTION_DESC_VLAN 6
+#define ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0
+#define ESF_DZ_TX_TIMESTAMP_LBN 5
+#define ESF_DZ_TX_TIMESTAMP_WIDTH 1
+#define ESF_DZ_TX_OPTION_CRC_MODE_LBN 2
+#define ESF_DZ_TX_OPTION_CRC_MODE_WIDTH 3
+#define ESE_DZ_TX_OPTION_CRC_FCOIP_MPA 5
+#define ESE_DZ_TX_OPTION_CRC_FCOIP_FCOE 4
+#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR_AND_PYLD 3
+#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR 2
+#define ESE_DZ_TX_OPTION_CRC_FCOE 1
+#define ESE_DZ_TX_OPTION_CRC_OFF 0
+#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_LBN 1
+#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_WIDTH 1
+#define ESF_DZ_TX_OPTION_IP_CSUM_LBN 0
+#define ESF_DZ_TX_OPTION_IP_CSUM_WIDTH 1
+
+
/* ES_TX_EVENT */
#define ESF_DZ_TX_CODE_LBN 60
#define ESF_DZ_TX_CODE_WIDTH 4
@@ -2198,10 +2323,12 @@ extern "C" {
#define ESF_DZ_TX_EV_RSVD_WIDTH 10
#define ESF_DZ_TX_SOFT2_LBN 32
#define ESF_DZ_TX_SOFT2_WIDTH 16
+#define ESF_DZ_TX_CAN_MERGE_LBN 31
+#define ESF_DZ_TX_CAN_MERGE_WIDTH 1
#define ESF_DZ_TX_SOFT1_LBN 24
-#define ESF_DZ_TX_SOFT1_WIDTH 8
+#define ESF_DZ_TX_SOFT1_WIDTH 7
#define ESF_DZ_TX_QLABEL_LBN 16
-#define ESF_DZ_TX_QLABEL_WIDTH 8
+#define ESF_DZ_TX_QLABEL_WIDTH 5
#define ESF_DZ_TX_DESCR_INDX_LBN 0
#define ESF_DZ_TX_DESCR_INDX_WIDTH 16
@@ -2221,305 +2348,33 @@ extern "C" {
#define ESF_DZ_TX_KER_BUF_ADDR_WIDTH 48
-/* ES_TX_OPTION_DESC */
+/* ES_TX_PIO_DESC */
+#define ESF_DZ_TX_PIO_TYPE_LBN 63
+#define ESF_DZ_TX_PIO_TYPE_WIDTH 1
+#define ESF_DZ_TX_PIO_OPT_LBN 60
+#define ESF_DZ_TX_PIO_OPT_WIDTH 3
+#define ESF_DZ_TX_PIO_CONT_LBN 59
+#define ESF_DZ_TX_PIO_CONT_WIDTH 1
+#define ESF_DZ_TX_PIO_BYTE_CNT_LBN 32
+#define ESF_DZ_TX_PIO_BYTE_CNT_WIDTH 12
+#define ESF_DZ_TX_PIO_BUF_ADDR_LBN 0
+#define ESF_DZ_TX_PIO_BUF_ADDR_WIDTH 12
+
+
+/* ES_TX_TSO_DESC */
#define ESF_DZ_TX_DESC_IS_OPT_LBN 63
#define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1
#define ESF_DZ_TX_OPTION_TYPE_LBN 60
#define ESF_DZ_TX_OPTION_TYPE_WIDTH 3
-#define ESE_DZ_TX_OPTION_DESC_TSO 4
+#define ESE_DZ_TX_OPTION_DESC_TSO 7
+#define ESE_DZ_TX_OPTION_DESC_VLAN 6
#define ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0
#define ESF_DZ_TX_TSO_TCP_FLAGS_LBN 48
#define ESF_DZ_TX_TSO_TCP_FLAGS_WIDTH 8
-#define ESF_DZ_TX_TSO_TCP_MSS_LBN 32
-#define ESF_DZ_TX_TSO_TCP_MSS_WIDTH 16
+#define ESF_DZ_TX_TSO_IP_ID_LBN 32
+#define ESF_DZ_TX_TSO_IP_ID_WIDTH 16
#define ESF_DZ_TX_TSO_TCP_SEQNO_LBN 0
#define ESF_DZ_TX_TSO_TCP_SEQNO_WIDTH 32
-#define ESF_DZ_TX_OPTION_CRC_MODE_LBN 2
-#define ESF_DZ_TX_OPTION_CRC_MODE_WIDTH 3
-#define ESE_DZ_TX_OPTION_CRC_FCOIP_MPA 5
-#define ESE_DZ_TX_OPTION_CRC_FCOIP_FCOE 4
-#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR_AND_PYLD 3
-#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR 2
-#define ESE_DZ_TX_OPTION_CRC_FCOE 1
-#define ESE_DZ_TX_OPTION_CRC_OFF 0
-#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_LBN 1
-#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_WIDTH 1
-#define ESF_DZ_TX_OPTION_IP_CSUM_LBN 0
-#define ESF_DZ_TX_OPTION_IP_CSUM_WIDTH 1
-
-
-/* ES_TX_PACER_BASE_MSG */
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW0_LBN 11
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW0_WIDTH 32
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW1_LBN 43
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW1_WIDTH 32
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW2_LBN 75
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW2_WIDTH 23
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_LBN 11
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_WIDTH 87
-#define ESF_DZ_TXP_BASE_OP_LBN 2
-#define ESF_DZ_TXP_BASE_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BASE_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BASE_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_D_R_REQ */
-#define ESF_DZ_TXP_BKT_D_R_REQ_FRM_LEN_LBN 45
-#define ESF_DZ_TXP_BKT_D_R_REQ_FRM_LEN_WIDTH 14
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT2_LBN 35
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT2_WIDTH 10
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT1_LBN 25
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT1_WIDTH 10
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT0_LBN 15
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT0_WIDTH 10
-#define ESF_DZ_TXP_BKT_D_R_REQ_MIN_BKT_LBN 5
-#define ESF_DZ_TXP_BKT_D_R_REQ_MIN_BKT_WIDTH 10
-#define ESF_DZ_TXP_BKT_D_R_REQ_OP_LBN 2
-#define ESF_DZ_TXP_BKT_D_R_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_D_R_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_D_R_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_TBL_D_R_RSP */
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WITH_MIN_BKT_LBN 21
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WITH_MIN_BKT_WIDTH 26
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_LBN 5
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_OP_LBN 2
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_TBL_RD_REQ */
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_BKT_ID_LBN 5
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_BKT_ID_WIDTH 10
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_OP_LBN 2
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_TBL_RD_RSP */
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_IDLE_LBN 97
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_IDLE_WIDTH 1
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_USED_LBN 96
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_USED_WIDTH 1
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_MAX_FILL_REG_LBN 94
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_MAX_FILL_REG_WIDTH 2
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_REC_LBN 78
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_REC_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_LBN 62
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_FILL_LEVEL_LBN 47
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_FILL_LEVEL_WIDTH 15
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_DUE_TIME_LBN 31
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_DUE_TIME_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_LAST_FILL_TIME_LBN 15
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_LAST_FILL_TIME_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_BKT_ID_LBN 5
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_BKT_ID_WIDTH 10
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_OP_LBN 2
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_TBL_WR_REQ */
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_IDLE_LBN 65
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_IDLE_WIDTH 1
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_USED_LBN 64
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_USED_WIDTH 1
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_MAX_FILL_REG_LBN 62
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_MAX_FILL_REG_WIDTH 2
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_REC_LBN 46
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_REC_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_LBN 30
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_FILL_LEVEL_LBN 15
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_FILL_LEVEL_WIDTH 15
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_BKT_ID_LBN 5
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_BKT_ID_WIDTH 10
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_OP_LBN 2
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_TXQ_D_R_I_REQ */
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_FRM_LEN_LBN 15
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_FRM_LEN_WIDTH 14
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_TXQ_ID_LBN 5
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_TXQ_ID_WIDTH 10
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_OP_LBN 2
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_TXQ_TBL_RD_REQ */
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_TXQ_ID_LBN 5
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_TXQ_ID_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_OP_LBN 2
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_TXQ_TBL_RD_RSP */
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT2_LBN 53
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT2_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT1_LBN 43
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT1_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT0_LBN 33
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT0_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MIN_BKT_LBN 23
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MIN_BKT_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_LABEL_LBN 19
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_LABEL_WIDTH 4
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_PQ_FLAGS_LBN 16
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_PQ_FLAGS_WIDTH 3
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_DSBL_LBN 15
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_DSBL_WIDTH 1
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_TXQ_ID_LBN 5
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_TXQ_ID_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_OP_LBN 2
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_TXQ_TBL_WR_REQ */
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT2_LBN 53
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT2_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT1_LBN 43
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT1_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT0_LBN 33
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT0_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MIN_BKT_LBN 23
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MIN_BKT_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_LABEL_LBN 19
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_LABEL_WIDTH 4
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_PQ_FLAGS_LBN 16
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_PQ_FLAGS_WIDTH 3
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_DSBL_LBN 15
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_DSBL_WIDTH 1
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_TXQ_ID_LBN 5
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_TXQ_ID_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_OP_LBN 2
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
/* ES_TX_USER_DESC */
@@ -2572,8 +2427,12 @@ extern "C" {
#define ESF_DZ_TX_U_DC_RPTR_WIDTH 6
#define ESF_DZ_TX_U_SOFT6_B1R1_LBN 80
#define ESF_DZ_TX_U_SOFT6_B1R1_WIDTH 6
+#define ESF_DZ_TX_U_CNTAG_LBN 68
+#define ESF_DZ_TX_U_CNTAG_WIDTH 1
#define ESF_DZ_TX_U_SOFT5_B1R0_LBN 64
#define ESF_DZ_TX_U_SOFT5_B1R0_WIDTH 5
+#define ESF_DZ_TX_U_TIMESTAMP_LBN 67
+#define ESF_DZ_TX_U_TIMESTAMP_WIDTH 1
#define ESF_DZ_TX_U_PREFETCH_ACTIVE_LBN 66
#define ESF_DZ_TX_U_PREFETCH_ACTIVE_WIDTH 1
#define ESF_DZ_TX_U_PREFETCH_PENDING_LBN 65
@@ -2613,6 +2472,18 @@ extern "C" {
#define ESF_DZ_TX_U_SOFT18_B1R0_WIDTH 18
#define ESF_DZ_TX_U_SOFT16_B0R3_LBN 48
#define ESF_DZ_TX_U_SOFT16_B0R3_WIDTH 16
+#define ESF_DZ_TX_U_EMERGENCY_FETCH_FAILED_LBN 56
+#define ESF_DZ_TX_U_EMERGENCY_FETCH_FAILED_WIDTH 1
+#define ESF_DZ_TX_U_PACER_BYPASS_OK_LBN 55
+#define ESF_DZ_TX_U_PACER_BYPASS_OK_WIDTH 1
+#define ESF_DZ_TX_U_STALE_DL_FETCH_LBN 54
+#define ESF_DZ_TX_U_STALE_DL_FETCH_WIDTH 1
+#define ESF_DZ_TX_U_ROLLBACK_IDX_REACHED_LBN 52
+#define ESF_DZ_TX_U_ROLLBACK_IDX_REACHED_WIDTH 1
+#define ESF_DZ_TX_U_ROLLBACK_ACTIVE_LBN 51
+#define ESF_DZ_TX_U_ROLLBACK_ACTIVE_WIDTH 1
+#define ESF_DZ_TX_U_QUEUE_PAUSED_LBN 50
+#define ESF_DZ_TX_U_QUEUE_PAUSED_WIDTH 1
#define ESF_DZ_TX_U_QUEUE_ENABLED_LBN 49
#define ESF_DZ_TX_U_QUEUE_ENABLED_WIDTH 1
#define ESF_DZ_TX_U_FLUSH_PENDING_LBN 48
@@ -2625,7 +2496,7 @@ extern "C" {
#define ESF_DZ_TX_U_OWNER_ID_WIDTH 12
#define ESF_DZ_TX_U_SOFT12_B0R1_LBN 16
#define ESF_DZ_TX_U_SOFT12_B0R1_WIDTH 12
-#define ESF_DZ_TX_U_DSCR_SIZE_LBN 0
+#define ESF_DZ_TX_U_DSCR_SIZE_LBN 13
#define ESF_DZ_TX_U_DSCR_SIZE_WIDTH 3
#define ESF_DZ_TX_U_SOFT3_B0R0_LBN 0
#define ESF_DZ_TX_U_SOFT3_B0R0_WIDTH 3
@@ -2642,9 +2513,27 @@ extern "C" {
#define ESF_DZ_TX_FINFO_SRCDST_WIDTH 16
+/* ES_TX_VLAN_DESC */
+#define ESF_DZ_TX_DESC_IS_OPT_LBN 63
+#define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1
+#define ESF_DZ_TX_OPTION_TYPE_LBN 60
+#define ESF_DZ_TX_OPTION_TYPE_WIDTH 3
+#define ESE_DZ_TX_OPTION_DESC_TSO 7
+#define ESE_DZ_TX_OPTION_DESC_VLAN 6
+#define ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0
+#define ESF_DZ_TX_VLAN_OP_LBN 32
+#define ESF_DZ_TX_VLAN_OP_WIDTH 2
+#define ESF_DZ_TX_VLAN_TAG2_LBN 16
+#define ESF_DZ_TX_VLAN_TAG2_WIDTH 16
+#define ESF_DZ_TX_VLAN_TAG1_LBN 0
+#define ESF_DZ_TX_VLAN_TAG1_WIDTH 16
+
+
/* ES_b2t_cpl_rsp */
-#define ESF_DZ_B2T_CPL_RSP_CPL_ECC_LBN 268
+#define ESF_DZ_B2T_CPL_RSP_CPL_ECC_LBN 284
#define ESF_DZ_B2T_CPL_RSP_CPL_ECC_WIDTH 32
+#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_LBN 283
+#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_WIDTH 1
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW0_LBN 27
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW0_WIDTH 32
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW1_LBN 59
@@ -2663,8 +2552,6 @@ extern "C" {
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW7_WIDTH 32
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_LBN 27
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_WIDTH 256
-#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_LBN 283
-#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_WIDTH -15
#define ESF_DZ_B2T_CPL_RSP_CPL_ERROR_LBN 26
#define ESF_DZ_B2T_CPL_RSP_CPL_ERROR_WIDTH 1
#define ESF_DZ_B2T_CPL_RSP_CPL_LAST_LBN 25
@@ -2677,95 +2564,321 @@ extern "C" {
#define ESF_DZ_B2T_CPL_RSP_CPL_ADRS_WIDTH 7
+/* ES_fltr_info_wrd_mac_to_rx */
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED2_LBN 112
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED2_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP2_LBN 96
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP2_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP1_LBN 80
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP0_LBN 64
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP0_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED1_LBN 48
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_IPSEC_SA_LBN 32
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_IPSEC_SA_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED0_LBN 8
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED0_WIDTH 24
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_mc_pdma */
+#define ESF_DZ_FLTR_INFO_MC_PDMA_FLTR_OUT_LBN 64
+#define ESF_DZ_FLTR_INFO_MC_PDMA_FLTR_OUT_WIDTH 16
+#define ESE_DZ_FLTR_MULTICAST_VLAN 512
+#define ESE_DZ_FLTR_MAC_VLAN 256
+#define ESE_DZ_FLTR_STRUCTURED7 128
+#define ESE_DZ_FLTR_STRUCTURED6 64
+#define ESE_DZ_FLTR_STRUCTURED5 32
+#define ESE_DZ_FLTR_STRUCTURED4 16
+#define ESE_DZ_FLTR_STRUCTURED3 8
+#define ESE_DZ_FLTR_STRUCTURED2 4
+#define ESE_DZ_FLTR_STRUCTURED1 2
+#define ESE_DZ_FLTR_STRUCTURED0 1
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_DW0_LBN 16
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_DW0_WIDTH 32
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_DW1_LBN 48
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_DW1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_LBN 16
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_WIDTH 48
+#define ESF_DZ_FLTR_INFO_MC_PDMA_DST_LBN 8
+#define ESF_DZ_FLTR_INFO_MC_PDMA_DST_WIDTH 8
+#define ESE_DZ_DST_NCSI 64
+#define ESE_DZ_DST_PORT0 32
+#define ESE_DZ_DST_PORT1 16
+#define ESE_DZ_DST_PORT0_IPSEC 8
+#define ESE_DZ_DST_PORT1_IPSEC 4
+#define ESE_DZ_DST_PM 2
+#define ESE_DZ_DST_TIMESTAMP 1
+#define ESF_DZ_FLTR_INFO_MC_PDMA_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_MC_PDMA_PRIORITY_WIDTH 4
+#define ESF_DZ_FLTR_INFO_MC_PDMA_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_MC_PDMA_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_rxdi_to_rxdp */
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_INNER_VLAN_LBN 112
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_INNER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_OUTER_VLAN_LBN 96
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_OUTER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_THASH1_LBN 80
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_THASH1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_THASH0_LBN 64
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_THASH0_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_TIMESTAMP1_LBN 48
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_TIMESTAMP1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_TIMESTAMP0_LBN 32
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_TIMESTAMP0_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_CNP_LBN 31
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_CNP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_IVP_LBN 30
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_IVP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_OVP_LBN 29
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_OVP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST2_LBN 28
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST2_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST1_LBN 27
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST0_LBN 26
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RX_QID_LBN 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RX_QID_WIDTH 10
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_HOST_LBN 15
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_HOST_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_MC_LBN 14
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_MC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_P0_LBN 13
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_P0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_P1_LBN 12
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_P1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RESERVED1_LBN 11
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RESERVED1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_CRF_LBN 10
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_CRF_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RESERVED0_LBN 9
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_REPLAY_LBN 8
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_REPLAY_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_rxdp_to_host */
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED3_LBN 33
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED3_WIDTH 31
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RMON_SOFT_LBN 32
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RMON_SOFT_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED2_LBN 27
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED2_WIDTH 5
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RX_QID_LBN 16
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RX_QID_WIDTH 11
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_HOST_LBN 15
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_HOST_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_MC_LBN 14
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_MC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_P0_LBN 13
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_P0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_P1_LBN 12
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_P1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED1_LBN 11
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_CRF_LBN 10
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_CRF_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED0_LBN 9
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_REPLAY_LBN 8
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_REPLAY_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_tx_to_mac */
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_PRV_LBN 63
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_PRV_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_LB_LBN 62
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_LB_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_MS0_LBN 61
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_MS0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_MS1_LBN 60
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_MS1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_NDI_LBN 59
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_NDI_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED2_LBN 48
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED2_WIDTH 11
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_IPSEC_SA_LBN 32
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_IPSEC_SA_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_TX_STACK_ID_LBN 24
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_TX_STACK_ID_WIDTH 8
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_TX_DOMAIN_LBN 16
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_TX_DOMAIN_WIDTH 8
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED1_LBN 14
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED1_WIDTH 2
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_P0_LBN 13
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_P0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_P1_LBN 12
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_P1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_IP0_LBN 11
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_IP0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_IP1_LBN 10
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_IP1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_PM_LBN 9
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_PM_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED0_LBN 8
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_txdi_to_txdp */
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_INNER_VLAN_LBN 112
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_INNER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_OUTER_VLAN_LBN 96
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_OUTER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_CNP_LBN 95
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_CNP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IVP_LBN 94
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IVP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_OVP_LBN 93
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_OVP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED4_LBN 90
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED4_WIDTH 3
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_QID_LBN 80
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_QID_WIDTH 10
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_VRI_LBN 79
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_VRI_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED3_LBN 78
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED3_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MTU_DIV4_LBN 66
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MTU_DIV4_WIDTH 12
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_VRI_OP_LBN 64
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_VRI_OP_WIDTH 2
+#define ESE_DZ_VRI_OP_INSERT_REPLACE 3
+#define ESE_DZ_VRI_OP_INSERT_INSERT 2
+#define ESE_DZ_VRI_OP_REPLACE 1
+#define ESE_DZ_VRI_OP_INSERT 0
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_PRV_LBN 63
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_PRV_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_LB_LBN 62
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_LB_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MS0_LBN 61
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MS0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MS1_LBN 60
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MS1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_NDI_LBN 59
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_NDI_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TXDP_CONTEXT_OUT_LBN 48
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TXDP_CONTEXT_OUT_WIDTH 11
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IPSEC_SA_LBN 32
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IPSEC_SA_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TX_STACK_ID_LBN 24
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TX_STACK_ID_WIDTH 8
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TX_DOMAIN_LBN 16
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TX_DOMAIN_WIDTH 8
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED1_LBN 14
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED1_WIDTH 2
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_P0_LBN 13
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_P0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_P1_LBN 12
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_P1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_IP0_LBN 11
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_IP0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_IP1_LBN 10
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_IP1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_PM_LBN 9
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_PM_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED0_LBN 8
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_txdp_to_txdi */
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_VLAN_OP_LBN 62
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_VLAN_OP_WIDTH 2
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_RESERVED1_LBN 58
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_RESERVED1_WIDTH 4
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_TX_QID_LBN 48
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_TX_QID_WIDTH 10
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_INNER_VLAN_LBN 32
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_INNER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_OUTER_VLAN_LBN 16
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_OUTER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_TXDP_CONTEXT_IN_LBN 5
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_TXDP_CONTEXT_IN_WIDTH 11
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_RESERVED0_LBN 4
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_SRC_WIDTH 4
+
+
+/* ES_nwk_ev_merge_blk_cmd */
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_OP_LBN 28
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_OP_WIDTH 4
+#define ESE_DZ_EV_MERGE_BLK_COMMAND_OP_FLUSH 2
+#define ESE_DZ_EV_MERGE_BLK_COMMAND_OP_ENABLE 1
+#define ESE_DZ_EV_MERGE_BLK_COMMAND_OP_DISABLE 0
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_BUSY_LBN 31
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_BUSY_WIDTH 1
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_EVQ_IDX_LBN 0
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_EVQ_IDX_WIDTH 11
+
+
+/* ES_txpm2ini_cpl_rsp */
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ECC_LBN 284
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ECC_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_EOT_LBN 283
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_EOT_WIDTH 1
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW0_LBN 27
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW0_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW1_LBN 59
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW1_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW2_LBN 91
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW2_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW3_LBN 123
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW3_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW4_LBN 155
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW4_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW5_LBN 187
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW5_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW6_LBN 219
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW6_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW7_LBN 251
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW7_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_LBN 27
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_WIDTH 256
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ERROR_LBN 26
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ERROR_WIDTH 1
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_LAST_LBN 25
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_LAST_WIDTH 1
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_TAG_LBN 19
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_TAG_WIDTH 6
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_LEN_LBN 7
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_LEN_WIDTH 12
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ADRS_LBN 0
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ADRS_WIDTH 7
+
-/* Enum DPCPU_INSTR_BRTYPE */
-#define ESE_DZ_BNEZAL 19
-#define ESE_DZ_BEQZAL 18
-#define ESE_DZ_BGEZAL 17
-#define ESE_DZ_BLTZAL 16
-#define ESE_DZ_BNEZ 3
-#define ESE_DZ_BEQZ 2
-#define ESE_DZ_BGEZ 1
-#define ESE_DZ_BLTZ 0
-
-/* Enum DPCPU_INSTR_FUNCT */
-#define ESE_DZ_MASKMOD 44
-#define ESE_DZ_SLTU 43
-#define ESE_DZ_SLT 42
-#define ESE_DZ_INCMOD 40
-#define ESE_DZ_NOR 39
-#define ESE_DZ_XOR 38
-#define ESE_DZ_OR 37
-#define ESE_DZ_AND 36
-#define ESE_DZ_SUBU 35
-#define ESE_DZ_SUB 34
-#define ESE_DZ_ADDU 33
-#define ESE_DZ_ADD 32
-#define ESE_DZ_MULT 25
-#define ESE_DZ_MFLO 18
-#define ESE_DZ_MFHI 16
-#define ESE_DZ_JALR 9
-#define ESE_DZ_JR 8
-#define ESE_DZ_SRAV 7
-#define ESE_DZ_SRLV 6
-#define ESE_DZ_SLLV 4
-#define ESE_DZ_SRA 3
-#define ESE_DZ_SRL 2
-#define ESE_DZ_SLL 0
-
-/* Enum DPCPU_INSTR_OP */
-#define ESE_DZ_LM_MSG 49
-#define ESE_DZ_MSG 48
-#define ESE_DZ_SHA 43
-#define ESE_DZ_SBA 42
-#define ESE_DZ_SH 41
-#define ESE_DZ_SB 40
-#define ESE_DZ_LHUA 39
-#define ESE_DZ_LBUA 38
-#define ESE_DZ_LHU 37
-#define ESE_DZ_LBU 36
-#define ESE_DZ_LHA 35
-#define ESE_DZ_LBA 34
-#define ESE_DZ_LH 33
-#define ESE_DZ_LB 32
-#define ESE_DZ_BGTU 31
-#define ESE_DZ_BLEU 30
-#define ESE_DZ_MODI 28
-#define ESE_DZ_NEGU 27
-#define ESE_DZ_NEG 26
-#define ESE_DZ_LI 25
-#define ESE_DZ_INCMODI 24
-#define ESE_DZ_BGT 23
-#define ESE_DZ_BLE 22
-#define ESE_DZ_BBS 21
-#define ESE_DZ_BBC 20
-#define ESE_DZ_JAL_EVT 19
-#define ESE_DZ_J_EVT 18
-#define ESE_DZ_HALT 16
-#define ESE_DZ_NORI 15
-#define ESE_DZ_XORI 14
-#define ESE_DZ_ORI 13
-#define ESE_DZ_ANDI 12
-#define ESE_DZ_SLTIU 11
-#define ESE_DZ_SLTI 10
-#define ESE_DZ_ADDIU 9
-#define ESE_DZ_ADDI 8
-#define ESE_DZ_BGTZ 7
-#define ESE_DZ_BLEZ 6
-#define ESE_DZ_BNE 5
-#define ESE_DZ_BEQ 4
-#define ESE_DZ_JAL 3
-#define ESE_DZ_J 2
-#define ESE_DZ_BRANCH 1
-#define ESE_DZ_REG2REG 0
-
-/* Enum DPCPU_MSG_DIR */
-#define ESE_DPCPU_MSG_DZ_OUTB 0x1
-#define ESE_DPCPU_MSG_DZ_INB 0x0
-
-/* Enum DPCPU_PDBUS_OP */
-#define ESE_DPCPU_PDBUS_DZ_RD 0x1
-#define ESE_DPCPU_PDBUS_DZ_WR 0x0
/* Enum INI_OP */
#define ESE_DZ_RD_COMPL 0x3
@@ -2778,6 +2891,19 @@ extern "C" {
#define ESE_DZ_MSI 0x1
#define ESE_DZ_MSIX 0x0
+/* Enum MC_PDMA_BUFFER_ID */
+#define ESE_DZ_MC_PDMA_BUFFER_ALL 4
+#define ESE_DZ_MC_PDMA_BUFFER_RXDP 3
+#define ESE_DZ_MC_PDMA_BUFFER_NCSI 2
+#define ESE_DZ_MC_PDMA_BUFFER_NWPORT1 1
+#define ESE_DZ_MC_PDMA_BUFFER_NWPORT0 0
+
+/* Enum MC_PDMA_INTERFACE_ID */
+#define ESE_DZ_MC_PDMA_INTERFACE_RXDP 3
+#define ESE_DZ_MC_PDMA_INTERFACE_NCSI 2
+#define ESE_DZ_MC_PDMA_INTERFACE_NWPORT1 1
+#define ESE_DZ_MC_PDMA_INTERFACE_NWPORT0 0
+
/* Enum PKT_STRM_CTL */
#define ESE_DZ_EOP_TRUNC 0x3
#define ESE_DZ_EOP_CRC_ERR 0x2
diff --git a/sys/dev/sfxge/common/efx_regs_mcdi.h b/sys/dev/sfxge/common/efx_regs_mcdi.h
index 9016ca9a4766..bd35970768ec 100644
--- a/sys/dev/sfxge/common/efx_regs_mcdi.h
+++ b/sys/dev/sfxge/common/efx_regs_mcdi.h
@@ -1,5 +1,5 @@
/*-
- * Copyright 2008-2011 Solarflare Communications Inc. All rights reserved.
+ * Copyright 2008-2013 Solarflare Communications Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,6 +39,17 @@
#define MC_FW_STATE_BOOTING (4)
/* The Scheduler has started. */
#define MC_FW_STATE_SCHED (8)
+/* If this is set in MC_RESET_STATE_REG then it should be
+ * possible to jump into IMEM without loading code from flash.
+ * Unlike a warm boot, assume DMEM has been reloaded, so that
+ * the MC persistent data must be reinitialised. */
+#define MC_FW_TEPID_BOOT_OK (16)
+/* We have entered the main firmware via recovery mode. This
+ * means that MC persistent data must be reinitialised, but that
+ * we shouldn't touch PCIe config. */
+#define MC_FW_RECOVERY_MODE_PCIE_INIT_OK (32)
+/* BIST state has been initialized */
+#define MC_FW_BIST_INIT_OK (128)
/* Siena MC shared memmory offsets */
/* The 'doorbell' addresses are hard-wired to alert the MC when written */
@@ -57,6 +68,9 @@
#define MC_STATUS_DWORD_REBOOT (0xb007b007)
#define MC_STATUS_DWORD_ASSERT (0xdeaddead)
+/* Check whether an mcfw version (in host order) belongs to a bootloader */
+#define MC_FW_VERSION_IS_BOOTLOADER(_v) (((_v) >> 16) == 0xb007)
+
/* The current version of the MCDI protocol.
*
* Note that the ROM burnt into the card only talks V0, so at the very
@@ -72,7 +86,7 @@
/* MCDI version 1
*
- * Each MCDI request starts with an MCDI_HEADER, which is a 32byte
+ * Each MCDI request starts with an MCDI_HEADER, which is a 32bit
* structure, filled in by the client.
*
* 0 7 8 16 20 22 23 24 31
@@ -109,9 +123,11 @@
#define MCDI_HEADER_DATALEN_LBN 8
#define MCDI_HEADER_DATALEN_WIDTH 8
#define MCDI_HEADER_SEQ_LBN 16
-#define MCDI_HEADER_RSVD_LBN 20
-#define MCDI_HEADER_RSVD_WIDTH 2
#define MCDI_HEADER_SEQ_WIDTH 4
+#define MCDI_HEADER_RSVD_LBN 20
+#define MCDI_HEADER_RSVD_WIDTH 1
+#define MCDI_HEADER_NOT_EPOCH_LBN 21
+#define MCDI_HEADER_NOT_EPOCH_WIDTH 1
#define MCDI_HEADER_ERROR_LBN 22
#define MCDI_HEADER_ERROR_WIDTH 1
#define MCDI_HEADER_RESPONSE_LBN 23
@@ -122,12 +138,16 @@
#define MCDI_HEADER_XFLAGS_EVREQ 0x01
/* Maximum number of payload bytes */
+#define MCDI_CTL_SDU_LEN_MAX_V1 0xfc
+#define MCDI_CTL_SDU_LEN_MAX_V2 0x400
+
#ifdef WITH_MCDI_V2
-#define MCDI_CTL_SDU_LEN_MAX 0x400
+#define MCDI_CTL_SDU_LEN_MAX MCDI_CTL_SDU_LEN_MAX_V2
#else
-#define MCDI_CTL_SDU_LEN_MAX 0xfc
+#define MCDI_CTL_SDU_LEN_MAX MCDI_CTL_SDU_LEN_MAX_V1
#endif
+
/* The MC can generate events for two reasons:
* - To complete a shared memory request if XFLAGS_EVREQ was set
* - As a notification (link state, i2c event), controlled
@@ -171,22 +191,114 @@
#define FSE_AZ_EV_CODE_MCDI_EVRESPONSE 0xc
+/* Operation not permitted. */
+#define MC_CMD_ERR_EPERM 1
/* Non-existent command target */
#define MC_CMD_ERR_ENOENT 2
/* assert() has killed the MC */
#define MC_CMD_ERR_EINTR 4
+/* I/O failure */
+#define MC_CMD_ERR_EIO 5
+/* Already exists */
+#define MC_CMD_ERR_EEXIST 6
+/* Try again */
+#define MC_CMD_ERR_EAGAIN 11
+/* Out of memory */
+#define MC_CMD_ERR_ENOMEM 12
/* Caller does not hold required locks */
#define MC_CMD_ERR_EACCES 13
/* Resource is currently unavailable (e.g. lock contention) */
#define MC_CMD_ERR_EBUSY 16
+/* No such device */
+#define MC_CMD_ERR_ENODEV 19
/* Invalid argument to target */
#define MC_CMD_ERR_EINVAL 22
+/* Broken pipe */
+#define MC_CMD_ERR_EPIPE 32
+/* Read-only */
+#define MC_CMD_ERR_EROFS 30
+/* Out of range */
+#define MC_CMD_ERR_ERANGE 34
/* Non-recursive resource is already acquired */
#define MC_CMD_ERR_EDEADLK 35
/* Operation not implemented */
#define MC_CMD_ERR_ENOSYS 38
/* Operation timed out */
#define MC_CMD_ERR_ETIME 62
+/* Link has been severed */
+#define MC_CMD_ERR_ENOLINK 67
+/* Protocol error */
+#define MC_CMD_ERR_EPROTO 71
+/* Operation not supported */
+#define MC_CMD_ERR_ENOTSUP 95
+/* Address not available */
+#define MC_CMD_ERR_EADDRNOTAVAIL 99
+/* Not connected */
+#define MC_CMD_ERR_ENOTCONN 107
+/* Operation already in progress */
+#define MC_CMD_ERR_EALREADY 114
+
+/* Resource allocation failed. */
+#define MC_CMD_ERR_ALLOC_FAIL 0x1000
+/* V-adaptor not found. */
+#define MC_CMD_ERR_NO_VADAPTOR 0x1001
+/* EVB port not found. */
+#define MC_CMD_ERR_NO_EVB_PORT 0x1002
+/* V-switch not found. */
+#define MC_CMD_ERR_NO_VSWITCH 0x1003
+/* Too many VLAN tags. */
+#define MC_CMD_ERR_VLAN_LIMIT 0x1004
+/* Bad PCI function number. */
+#define MC_CMD_ERR_BAD_PCI_FUNC 0x1005
+/* Invalid VLAN mode. */
+#define MC_CMD_ERR_BAD_VLAN_MODE 0x1006
+/* Invalid v-switch type. */
+#define MC_CMD_ERR_BAD_VSWITCH_TYPE 0x1007
+/* Invalid v-port type. */
+#define MC_CMD_ERR_BAD_VPORT_TYPE 0x1008
+/* MAC address exists. */
+#define MC_CMD_ERR_MAC_EXIST 0x1009
+/* Slave core not present */
+#define MC_CMD_ERR_SLAVE_NOT_PRESENT 0x100a
+/* The datapath is disabled. */
+#define MC_CMD_ERR_DATAPATH_DISABLED 0x100b
+/* The requesting client is not a function */
+#define MC_CMD_ERR_CLIENT_NOT_FN 0x100c
+/* The requested operation might require the
+ command to be passed between MCs, and the
+ transport doesn't support that. Should
+ only ever been seen over the UART. */
+#define MC_CMD_ERR_TRANSPORT_NOPROXY 0x100d
+/* VLAN tag(s) exists */
+#define MC_CMD_ERR_VLAN_EXIST 0x100e
+/* No MAC address assigned to an EVB port */
+#define MC_CMD_ERR_NO_MAC_ADDR 0x100f
+/* Notifies the driver that the request has been relayed
+ * to an admin function for authorization. The driver should
+ * wait for a PROXY_RESPONSE event and then resend its request.
+ * This error code is followed by a 32-bit handle that
+ * helps matching it with the respective PROXY_RESPONSE event. */
+#define MC_CMD_ERR_PROXY_PENDING 0x1010
+#define MC_CMD_ERR_PROXY_PENDING_HANDLE_OFST 4
+/* The request cannot be passed for authorization because
+ * another request from the same function is currently being
+ * authorized. The drvier should try again later. */
+#define MC_CMD_ERR_PROXY_INPROGRESS 0x1011
+/* Returned by MC_CMD_PROXY_COMPLETE if the caller is not the function
+ * that has enabled proxying or BLOCK_INDEX points to a function that
+ * doesn't await an authorization. */
+#define MC_CMD_ERR_PROXY_UNEXPECTED 0x1012
+/* This code is currently only used internally in FW. Its meaning is that
+ * an operation failed due to lack of SR-IOV privilege.
+ * Normally it is translated to EPERM by send_cmd_err(),
+ * but it may also be used to trigger some special mechanism
+ * for handling such case, e.g. to relay the failed request
+ * to a designated admin function for authorization. */
+#define MC_CMD_ERR_NO_PRIVILEGE 0x1013
+/* Workaround 26807 could not be turned on/off because some functions
+ * have already installed filters. See the comment at
+ * MC_CMD_WORKAROUND_BUG26807. */
+#define MC_CMD_ERR_FILTERS_PRESENT 0x1014
#define MC_CMD_ERR_CODE_OFST 0
@@ -204,9 +316,11 @@
/* Vectors in the boot ROM */
/* Point to the copycode entry point. */
-#define MC_BOOTROM_COPYCODE_VEC (0x7f4)
+#define SIENA_MC_BOOTROM_COPYCODE_VEC (0x800 - 3 * 0x4)
+#define HUNT_MC_BOOTROM_COPYCODE_VEC (0x8000 - 3 * 0x4)
/* Points to the recovery mode entry point. */
-#define MC_BOOTROM_NOFLASH_VEC (0x7f8)
+#define SIENA_MC_BOOTROM_NOFLASH_VEC (0x800 - 2 * 0x4)
+#define HUNT_MC_BOOTROM_NOFLASH_VEC (0x8000 - 2 * 0x4)
/* The command set exported by the boot ROM (MCDI v0) */
#define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS { \
@@ -216,23 +330,28 @@
(1 << MC_CMD_GET_VERSION), \
0, 0, 0 }
-#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \
+#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \
(MC_CMD_SENSOR_ENTRY_OFST + (_x))
-#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(n) ( \
- (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \
- MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST)+ \
- ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN))
+#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(n) \
+ (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \
+ MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST + \
+ (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
-#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(n) ( \
- (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \
- MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST)+ \
- ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN))
+#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(n) \
+ (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \
+ MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST + \
+ (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
-#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(n) ( \
- (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \
- MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST)+ \
- ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN))
+#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(n) \
+ (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \
+ MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST + \
+ (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
+
+/* This may be ORed with an EVB_PORT_ID_xxx constant to pass a non-default
+ * stack ID (which must be in the range 1-255) along with an EVB port ID.
+ */
+#define EVB_STACK_ID(n) (((n) & 0xff) << 16)
#ifdef WITH_MCDI_V2
@@ -243,8 +362,6 @@
*/
#define MC_CMD_ERR_ARG_OFST 4
-/* Try again */
-#define MC_CMD_ERR_EAGAIN 11
/* No space */
#define MC_CMD_ERR_ENOSPC 28
@@ -256,10 +373,14 @@
#define MCDI_EVENT_CONT_WIDTH 1
#define MCDI_EVENT_LEVEL_LBN 33
#define MCDI_EVENT_LEVEL_WIDTH 3
-#define MCDI_EVENT_LEVEL_INFO 0x0 /* enum */
-#define MCDI_EVENT_LEVEL_WARN 0x1 /* enum */
-#define MCDI_EVENT_LEVEL_ERR 0x2 /* enum */
-#define MCDI_EVENT_LEVEL_FATAL 0x3 /* enum */
+/* enum: Info. */
+#define MCDI_EVENT_LEVEL_INFO 0x0
+/* enum: Warning. */
+#define MCDI_EVENT_LEVEL_WARN 0x1
+/* enum: Error. */
+#define MCDI_EVENT_LEVEL_ERR 0x2
+/* enum: Fatal. */
+#define MCDI_EVENT_LEVEL_FATAL 0x3
#define MCDI_EVENT_DATA_OFST 0
#define MCDI_EVENT_CMDDONE_SEQ_LBN 0
#define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8
@@ -271,9 +392,14 @@
#define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16
#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16
#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4
-#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1 /* enum */
-#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2 /* enum */
-#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3 /* enum */
+/* enum: 100Mbs */
+#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1
+/* enum: 1Gbs */
+#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2
+/* enum: 10Gbs */
+#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3
+/* enum: 40Gbs */
+#define MCDI_EVENT_LINKCHANGE_SPEED_40G 0x4
#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20
#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4
#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24
@@ -288,41 +414,94 @@
#define MCDI_EVENT_FWALERT_DATA_WIDTH 24
#define MCDI_EVENT_FWALERT_REASON_LBN 0
#define MCDI_EVENT_FWALERT_REASON_WIDTH 8
-#define MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1 /* enum */
+/* enum: SRAM Access. */
+#define MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1
#define MCDI_EVENT_FLR_VF_LBN 0
#define MCDI_EVENT_FLR_VF_WIDTH 8
#define MCDI_EVENT_TX_ERR_TXQ_LBN 0
#define MCDI_EVENT_TX_ERR_TXQ_WIDTH 12
#define MCDI_EVENT_TX_ERR_TYPE_LBN 12
#define MCDI_EVENT_TX_ERR_TYPE_WIDTH 4
-#define MCDI_EVENT_TX_ERR_DL_FAIL 0x1 /* enum */
-#define MCDI_EVENT_TX_ERR_NO_EOP 0x2 /* enum */
-#define MCDI_EVENT_TX_ERR_2BIG 0x3 /* enum */
+/* enum: Descriptor loader reported failure */
+#define MCDI_EVENT_TX_ERR_DL_FAIL 0x1
+/* enum: Descriptor ring empty and no EOP seen for packet */
+#define MCDI_EVENT_TX_ERR_NO_EOP 0x2
+/* enum: Overlength packet */
+#define MCDI_EVENT_TX_ERR_2BIG 0x3
+/* enum: Malformed option descriptor */
+#define MCDI_EVENT_TX_BAD_OPTDESC 0x5
+/* enum: Option descriptor part way through a packet */
+#define MCDI_EVENT_TX_OPT_IN_PKT 0x8
+/* enum: DMA or PIO data access error */
+#define MCDI_EVENT_TX_ERR_BAD_DMA_OR_PIO 0x9
#define MCDI_EVENT_TX_ERR_INFO_LBN 16
#define MCDI_EVENT_TX_ERR_INFO_WIDTH 16
+#define MCDI_EVENT_TX_FLUSH_TO_DRIVER_LBN 12
+#define MCDI_EVENT_TX_FLUSH_TO_DRIVER_WIDTH 1
#define MCDI_EVENT_TX_FLUSH_TXQ_LBN 0
#define MCDI_EVENT_TX_FLUSH_TXQ_WIDTH 12
#define MCDI_EVENT_PTP_ERR_TYPE_LBN 0
#define MCDI_EVENT_PTP_ERR_TYPE_WIDTH 8
-#define MCDI_EVENT_PTP_ERR_PLL_LOST 0x1 /* enum */
-#define MCDI_EVENT_PTP_ERR_FILTER 0x2 /* enum */
-#define MCDI_EVENT_PTP_ERR_FIFO 0x3 /* enum */
-#define MCDI_EVENT_PTP_ERR_QUEUE 0x4 /* enum */
+/* enum: PLL lost lock */
+#define MCDI_EVENT_PTP_ERR_PLL_LOST 0x1
+/* enum: Filter overflow (PDMA) */
+#define MCDI_EVENT_PTP_ERR_FILTER 0x2
+/* enum: FIFO overflow (FPGA) */
+#define MCDI_EVENT_PTP_ERR_FIFO 0x3
+/* enum: Merge queue overflow */
+#define MCDI_EVENT_PTP_ERR_QUEUE 0x4
#define MCDI_EVENT_AOE_ERR_TYPE_LBN 0
#define MCDI_EVENT_AOE_ERR_TYPE_WIDTH 8
-#define MCDI_EVENT_AOE_NO_LOAD 0x1 /* enum */
-#define MCDI_EVENT_AOE_FC_ASSERT 0x2 /* enum */
-#define MCDI_EVENT_AOE_FC_WATCHDOG 0x3 /* enum */
-#define MCDI_EVENT_AOE_FC_NO_START 0x4 /* enum */
-#define MCDI_EVENT_AOE_FAULT 0x5 /* enum */
-#define MCDI_EVENT_AOE_CPLD_REPROGRAMMED 0x6 /* enum */
-#define MCDI_EVENT_AOE_LOAD 0x7 /* enum */
-#define MCDI_EVENT_AOE_DMA 0x8 /* enum */
-#define MCDI_EVENT_AOE_BYTEBLASTER 0x9 /* enum */
-#define MCDI_EVENT_AOE_DDR_ECC_STATUS 0xa /* enum */
-#define MCDI_EVENT_AOE_PTP_STATUS 0xb /* enum */
+/* enum: AOE failed to load - no valid image? */
+#define MCDI_EVENT_AOE_NO_LOAD 0x1
+/* enum: AOE FC reported an exception */
+#define MCDI_EVENT_AOE_FC_ASSERT 0x2
+/* enum: AOE FC watchdogged */
+#define MCDI_EVENT_AOE_FC_WATCHDOG 0x3
+/* enum: AOE FC failed to start */
+#define MCDI_EVENT_AOE_FC_NO_START 0x4
+/* enum: Generic AOE fault - likely to have been reported via other means too
+ * but intended for use by aoex driver.
+ */
+#define MCDI_EVENT_AOE_FAULT 0x5
+/* enum: Results of reprogramming the CPLD (status in AOE_ERR_DATA) */
+#define MCDI_EVENT_AOE_CPLD_REPROGRAMMED 0x6
+/* enum: AOE loaded successfully */
+#define MCDI_EVENT_AOE_LOAD 0x7
+/* enum: AOE DMA operation completed (LSB of HOST_HANDLE in AOE_ERR_DATA) */
+#define MCDI_EVENT_AOE_DMA 0x8
+/* enum: AOE byteblaster connected/disconnected (Connection status in
+ * AOE_ERR_DATA)
+ */
+#define MCDI_EVENT_AOE_BYTEBLASTER 0x9
+/* enum: DDR ECC status update */
+#define MCDI_EVENT_AOE_DDR_ECC_STATUS 0xa
+/* enum: PTP status update */
+#define MCDI_EVENT_AOE_PTP_STATUS 0xb
#define MCDI_EVENT_AOE_ERR_DATA_LBN 8
#define MCDI_EVENT_AOE_ERR_DATA_WIDTH 8
+#define MCDI_EVENT_RX_ERR_RXQ_LBN 0
+#define MCDI_EVENT_RX_ERR_RXQ_WIDTH 12
+#define MCDI_EVENT_RX_ERR_TYPE_LBN 12
+#define MCDI_EVENT_RX_ERR_TYPE_WIDTH 4
+#define MCDI_EVENT_RX_ERR_INFO_LBN 16
+#define MCDI_EVENT_RX_ERR_INFO_WIDTH 16
+#define MCDI_EVENT_RX_FLUSH_TO_DRIVER_LBN 12
+#define MCDI_EVENT_RX_FLUSH_TO_DRIVER_WIDTH 1
+#define MCDI_EVENT_RX_FLUSH_RXQ_LBN 0
+#define MCDI_EVENT_RX_FLUSH_RXQ_WIDTH 12
+#define MCDI_EVENT_MC_REBOOT_COUNT_LBN 0
+#define MCDI_EVENT_MC_REBOOT_COUNT_WIDTH 16
+#define MCDI_EVENT_MUM_ERR_TYPE_LBN 0
+#define MCDI_EVENT_MUM_ERR_TYPE_WIDTH 8
+/* enum: MUM failed to load - no valid image? */
+#define MCDI_EVENT_MUM_NO_LOAD 0x1
+/* enum: MUM f/w reported an exception */
+#define MCDI_EVENT_MUM_ASSERT 0x2
+/* enum: MUM not kicking watchdog */
+#define MCDI_EVENT_MUM_WATCHDOG 0x3
+#define MCDI_EVENT_MUM_ERR_DATA_LBN 8
+#define MCDI_EVENT_MUM_ERR_DATA_WIDTH 8
#define MCDI_EVENT_DATA_LBN 0
#define MCDI_EVENT_DATA_WIDTH 32
#define MCDI_EVENT_SRC_LBN 36
@@ -331,24 +510,74 @@
#define MCDI_EVENT_EV_CODE_WIDTH 4
#define MCDI_EVENT_CODE_LBN 44
#define MCDI_EVENT_CODE_WIDTH 8
-#define MCDI_EVENT_CODE_BADSSERT 0x1 /* enum */
-#define MCDI_EVENT_CODE_PMNOTICE 0x2 /* enum */
-#define MCDI_EVENT_CODE_CMDDONE 0x3 /* enum */
-#define MCDI_EVENT_CODE_LINKCHANGE 0x4 /* enum */
-#define MCDI_EVENT_CODE_SENSOREVT 0x5 /* enum */
-#define MCDI_EVENT_CODE_SCHEDERR 0x6 /* enum */
-#define MCDI_EVENT_CODE_REBOOT 0x7 /* enum */
-#define MCDI_EVENT_CODE_MAC_STATS_DMA 0x8 /* enum */
-#define MCDI_EVENT_CODE_FWALERT 0x9 /* enum */
-#define MCDI_EVENT_CODE_FLR 0xa /* enum */
-#define MCDI_EVENT_CODE_TX_ERR 0xb /* enum */
-#define MCDI_EVENT_CODE_TX_FLUSH 0xc /* enum */
-#define MCDI_EVENT_CODE_PTP_RX 0xd /* enum */
-#define MCDI_EVENT_CODE_PTP_FAULT 0xe /* enum */
-#define MCDI_EVENT_CODE_PTP_PPS 0xf /* enum */
-#define MCDI_EVENT_CODE_AOE 0x12 /* enum */
-#define MCDI_EVENT_CODE_VCAL_FAIL 0x13 /* enum */
-#define MCDI_EVENT_CODE_HW_PPS 0x14 /* enum */
+/* enum: Event generated by host software */
+#define MCDI_EVENT_SW_EVENT 0x0
+/* enum: Bad assert. */
+#define MCDI_EVENT_CODE_BADSSERT 0x1
+/* enum: PM Notice. */
+#define MCDI_EVENT_CODE_PMNOTICE 0x2
+/* enum: Command done. */
+#define MCDI_EVENT_CODE_CMDDONE 0x3
+/* enum: Link change. */
+#define MCDI_EVENT_CODE_LINKCHANGE 0x4
+/* enum: Sensor Event. */
+#define MCDI_EVENT_CODE_SENSOREVT 0x5
+/* enum: Schedule error. */
+#define MCDI_EVENT_CODE_SCHEDERR 0x6
+/* enum: Reboot. */
+#define MCDI_EVENT_CODE_REBOOT 0x7
+/* enum: Mac stats DMA. */
+#define MCDI_EVENT_CODE_MAC_STATS_DMA 0x8
+/* enum: Firmware alert. */
+#define MCDI_EVENT_CODE_FWALERT 0x9
+/* enum: Function level reset. */
+#define MCDI_EVENT_CODE_FLR 0xa
+/* enum: Transmit error */
+#define MCDI_EVENT_CODE_TX_ERR 0xb
+/* enum: Tx flush has completed */
+#define MCDI_EVENT_CODE_TX_FLUSH 0xc
+/* enum: PTP packet received timestamp */
+#define MCDI_EVENT_CODE_PTP_RX 0xd
+/* enum: PTP NIC failure */
+#define MCDI_EVENT_CODE_PTP_FAULT 0xe
+/* enum: PTP PPS event */
+#define MCDI_EVENT_CODE_PTP_PPS 0xf
+/* enum: Rx flush has completed */
+#define MCDI_EVENT_CODE_RX_FLUSH 0x10
+/* enum: Receive error */
+#define MCDI_EVENT_CODE_RX_ERR 0x11
+/* enum: AOE fault */
+#define MCDI_EVENT_CODE_AOE 0x12
+/* enum: Network port calibration failed (VCAL). */
+#define MCDI_EVENT_CODE_VCAL_FAIL 0x13
+/* enum: HW PPS event */
+#define MCDI_EVENT_CODE_HW_PPS 0x14
+/* enum: The MC has rebooted (huntington and later, siena uses CODE_REBOOT and
+ * a different format)
+ */
+#define MCDI_EVENT_CODE_MC_REBOOT 0x15
+/* enum: the MC has detected a parity error */
+#define MCDI_EVENT_CODE_PAR_ERR 0x16
+/* enum: the MC has detected a correctable error */
+#define MCDI_EVENT_CODE_ECC_CORR_ERR 0x17
+/* enum: the MC has detected an uncorrectable error */
+#define MCDI_EVENT_CODE_ECC_FATAL_ERR 0x18
+/* enum: The MC has entered offline BIST mode */
+#define MCDI_EVENT_CODE_MC_BIST 0x19
+/* enum: PTP tick event providing current NIC time */
+#define MCDI_EVENT_CODE_PTP_TIME 0x1a
+/* enum: MUM fault */
+#define MCDI_EVENT_CODE_MUM 0x1b
+/* enum: notify the designated PF of a new authorization request */
+#define MCDI_EVENT_CODE_PROXY_REQUEST 0x1c
+/* enum: notify a function that awaits an authorization that its request has
+ * been processed and it may now resend the command
+ */
+#define MCDI_EVENT_CODE_PROXY_RESPONSE 0x1d
+/* enum: Artificial event generated by host and posted via MC for test
+ * purposes.
+ */
+#define MCDI_EVENT_CODE_TESTGEN 0xfa
#define MCDI_EVENT_CMDDONE_DATA_OFST 0
#define MCDI_EVENT_CMDDONE_DATA_LBN 0
#define MCDI_EVENT_CMDDONE_DATA_WIDTH 32
@@ -364,15 +593,81 @@
#define MCDI_EVENT_TX_ERR_DATA_OFST 0
#define MCDI_EVENT_TX_ERR_DATA_LBN 0
#define MCDI_EVENT_TX_ERR_DATA_WIDTH 32
+/* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the seconds field of
+ * timestamp
+ */
#define MCDI_EVENT_PTP_SECONDS_OFST 0
#define MCDI_EVENT_PTP_SECONDS_LBN 0
#define MCDI_EVENT_PTP_SECONDS_WIDTH 32
+/* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the major field of
+ * timestamp
+ */
+#define MCDI_EVENT_PTP_MAJOR_OFST 0
+#define MCDI_EVENT_PTP_MAJOR_LBN 0
+#define MCDI_EVENT_PTP_MAJOR_WIDTH 32
+/* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the nanoseconds field
+ * of timestamp
+ */
#define MCDI_EVENT_PTP_NANOSECONDS_OFST 0
#define MCDI_EVENT_PTP_NANOSECONDS_LBN 0
#define MCDI_EVENT_PTP_NANOSECONDS_WIDTH 32
+/* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the minor field of
+ * timestamp
+ */
+#define MCDI_EVENT_PTP_MINOR_OFST 0
+#define MCDI_EVENT_PTP_MINOR_LBN 0
+#define MCDI_EVENT_PTP_MINOR_WIDTH 32
+/* For CODE_PTP_RX events, the lowest four bytes of sourceUUID from PTP packet
+ */
#define MCDI_EVENT_PTP_UUID_OFST 0
#define MCDI_EVENT_PTP_UUID_LBN 0
#define MCDI_EVENT_PTP_UUID_WIDTH 32
+#define MCDI_EVENT_RX_ERR_DATA_OFST 0
+#define MCDI_EVENT_RX_ERR_DATA_LBN 0
+#define MCDI_EVENT_RX_ERR_DATA_WIDTH 32
+#define MCDI_EVENT_PAR_ERR_DATA_OFST 0
+#define MCDI_EVENT_PAR_ERR_DATA_LBN 0
+#define MCDI_EVENT_PAR_ERR_DATA_WIDTH 32
+#define MCDI_EVENT_ECC_CORR_ERR_DATA_OFST 0
+#define MCDI_EVENT_ECC_CORR_ERR_DATA_LBN 0
+#define MCDI_EVENT_ECC_CORR_ERR_DATA_WIDTH 32
+#define MCDI_EVENT_ECC_FATAL_ERR_DATA_OFST 0
+#define MCDI_EVENT_ECC_FATAL_ERR_DATA_LBN 0
+#define MCDI_EVENT_ECC_FATAL_ERR_DATA_WIDTH 32
+/* For CODE_PTP_TIME events, the major value of the PTP clock */
+#define MCDI_EVENT_PTP_TIME_MAJOR_OFST 0
+#define MCDI_EVENT_PTP_TIME_MAJOR_LBN 0
+#define MCDI_EVENT_PTP_TIME_MAJOR_WIDTH 32
+/* For CODE_PTP_TIME events, bits 19-26 of the minor value of the PTP clock */
+#define MCDI_EVENT_PTP_TIME_MINOR_26_19_LBN 36
+#define MCDI_EVENT_PTP_TIME_MINOR_26_19_WIDTH 8
+/* For CODE_PTP_TIME events where report sync status is enabled, indicates
+ * whether the NIC clock has ever been set
+ */
+#define MCDI_EVENT_PTP_TIME_NIC_CLOCK_VALID_LBN 36
+#define MCDI_EVENT_PTP_TIME_NIC_CLOCK_VALID_WIDTH 1
+/* For CODE_PTP_TIME events where report sync status is enabled, indicates
+ * whether the NIC and System clocks are in sync
+ */
+#define MCDI_EVENT_PTP_TIME_HOST_NIC_IN_SYNC_LBN 37
+#define MCDI_EVENT_PTP_TIME_HOST_NIC_IN_SYNC_WIDTH 1
+/* For CODE_PTP_TIME events where report sync status is enabled, bits 21-26 of
+ * the minor value of the PTP clock
+ */
+#define MCDI_EVENT_PTP_TIME_MINOR_26_21_LBN 38
+#define MCDI_EVENT_PTP_TIME_MINOR_26_21_WIDTH 6
+#define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_OFST 0
+#define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_LBN 0
+#define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_WIDTH 32
+#define MCDI_EVENT_PROXY_RESPONSE_HANDLE_OFST 0
+#define MCDI_EVENT_PROXY_RESPONSE_HANDLE_LBN 0
+#define MCDI_EVENT_PROXY_RESPONSE_HANDLE_WIDTH 32
+/* Zero means that the request has been completed or authorized, and the driver
+ * should resend it. A non-zero value means that the authorization has been
+ * denied, and gives the reason. Typically it will be EPERM.
+ */
+#define MCDI_EVENT_PROXY_RESPONSE_RC_LBN 36
+#define MCDI_EVENT_PROXY_RESPONSE_RC_WIDTH 8
/* FCDI_EVENT structuredef */
#define FCDI_EVENT_LEN 8
@@ -380,10 +675,14 @@
#define FCDI_EVENT_CONT_WIDTH 1
#define FCDI_EVENT_LEVEL_LBN 33
#define FCDI_EVENT_LEVEL_WIDTH 3
-#define FCDI_EVENT_LEVEL_INFO 0x0 /* enum */
-#define FCDI_EVENT_LEVEL_WARN 0x1 /* enum */
-#define FCDI_EVENT_LEVEL_ERR 0x2 /* enum */
-#define FCDI_EVENT_LEVEL_FATAL 0x3 /* enum */
+/* enum: Info. */
+#define FCDI_EVENT_LEVEL_INFO 0x0
+/* enum: Warning. */
+#define FCDI_EVENT_LEVEL_WARN 0x1
+/* enum: Error. */
+#define FCDI_EVENT_LEVEL_ERR 0x2
+/* enum: Fatal. */
+#define FCDI_EVENT_LEVEL_FATAL 0x3
#define FCDI_EVENT_DATA_OFST 0
#define FCDI_EVENT_LINK_STATE_STATUS_LBN 0
#define FCDI_EVENT_LINK_STATE_STATUS_WIDTH 1
@@ -397,15 +696,26 @@
#define FCDI_EVENT_EV_CODE_WIDTH 4
#define FCDI_EVENT_CODE_LBN 44
#define FCDI_EVENT_CODE_WIDTH 8
-#define FCDI_EVENT_CODE_REBOOT 0x1 /* enum */
-#define FCDI_EVENT_CODE_ASSERT 0x2 /* enum */
-#define FCDI_EVENT_CODE_DDR_TEST_RESULT 0x3 /* enum */
-#define FCDI_EVENT_CODE_LINK_STATE 0x4 /* enum */
-#define FCDI_EVENT_CODE_TIMED_READ 0x5 /* enum */
-#define FCDI_EVENT_CODE_PPS_IN 0x6 /* enum */
-#define FCDI_EVENT_CODE_PTP_TICK 0x7 /* enum */
-#define FCDI_EVENT_CODE_DDR_ECC_STATUS 0x8 /* enum */
-#define FCDI_EVENT_CODE_PTP_STATUS 0x9 /* enum */
+/* enum: The FC was rebooted. */
+#define FCDI_EVENT_CODE_REBOOT 0x1
+/* enum: Bad assert. */
+#define FCDI_EVENT_CODE_ASSERT 0x2
+/* enum: DDR3 test result. */
+#define FCDI_EVENT_CODE_DDR_TEST_RESULT 0x3
+/* enum: Link status. */
+#define FCDI_EVENT_CODE_LINK_STATE 0x4
+/* enum: A timed read is ready to be serviced. */
+#define FCDI_EVENT_CODE_TIMED_READ 0x5
+/* enum: One or more PPS IN events */
+#define FCDI_EVENT_CODE_PPS_IN 0x6
+/* enum: Tick event from PTP clock */
+#define FCDI_EVENT_CODE_PTP_TICK 0x7
+/* enum: ECC error counters */
+#define FCDI_EVENT_CODE_DDR_ECC_STATUS 0x8
+/* enum: Current status of PTP */
+#define FCDI_EVENT_CODE_PTP_STATUS 0x9
+/* enum: Port id config to map MC-FC port idx */
+#define FCDI_EVENT_CODE_PORT_CONFIG 0xa
#define FCDI_EVENT_ASSERT_INSTR_ADDRESS_OFST 0
#define FCDI_EVENT_ASSERT_INSTR_ADDRESS_LBN 0
#define FCDI_EVENT_ASSERT_INSTR_ADDRESS_WIDTH 32
@@ -430,20 +740,36 @@
#define FCDI_EVENT_DDR_ECC_STATUS_STATUS_OFST 0
#define FCDI_EVENT_DDR_ECC_STATUS_STATUS_LBN 0
#define FCDI_EVENT_DDR_ECC_STATUS_STATUS_WIDTH 32
-
-/* FCDI_EXTENDED_EVENT_PPS structuredef */
+/* Index of MC port being referred to */
+#define FCDI_EVENT_PORT_CONFIG_SRC_LBN 36
+#define FCDI_EVENT_PORT_CONFIG_SRC_WIDTH 8
+/* FC Port index that matches the MC port index in SRC */
+#define FCDI_EVENT_PORT_CONFIG_DATA_OFST 0
+#define FCDI_EVENT_PORT_CONFIG_DATA_LBN 0
+#define FCDI_EVENT_PORT_CONFIG_DATA_WIDTH 32
+
+/* FCDI_EXTENDED_EVENT_PPS structuredef: Extended FCDI event to send PPS events
+ * to the MC. Note that this structure | is overlayed over a normal FCDI event
+ * such that bits 32-63 containing | event code, level, source etc remain the
+ * same. In this case the data | field of the header is defined to be the
+ * number of timestamps
+ */
#define FCDI_EXTENDED_EVENT_PPS_LENMIN 16
#define FCDI_EXTENDED_EVENT_PPS_LENMAX 248
#define FCDI_EXTENDED_EVENT_PPS_LEN(num) (8+8*(num))
+/* Number of timestamps following */
#define FCDI_EXTENDED_EVENT_PPS_COUNT_OFST 0
#define FCDI_EXTENDED_EVENT_PPS_COUNT_LBN 0
#define FCDI_EXTENDED_EVENT_PPS_COUNT_WIDTH 32
+/* Seconds field of a timestamp record */
#define FCDI_EXTENDED_EVENT_PPS_SECONDS_OFST 8
#define FCDI_EXTENDED_EVENT_PPS_SECONDS_LBN 64
#define FCDI_EXTENDED_EVENT_PPS_SECONDS_WIDTH 32
+/* Nanoseconds field of a timestamp record */
#define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_OFST 12
#define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_LBN 96
#define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_WIDTH 32
+/* Timestamp records comprising the event */
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_OFST 8
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LEN 8
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LO_OFST 8
@@ -453,12 +779,99 @@
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LBN 64
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_WIDTH 64
+/* MUM_EVENT structuredef */
+#define MUM_EVENT_LEN 8
+#define MUM_EVENT_CONT_LBN 32
+#define MUM_EVENT_CONT_WIDTH 1
+#define MUM_EVENT_LEVEL_LBN 33
+#define MUM_EVENT_LEVEL_WIDTH 3
+/* enum: Info. */
+#define MUM_EVENT_LEVEL_INFO 0x0
+/* enum: Warning. */
+#define MUM_EVENT_LEVEL_WARN 0x1
+/* enum: Error. */
+#define MUM_EVENT_LEVEL_ERR 0x2
+/* enum: Fatal. */
+#define MUM_EVENT_LEVEL_FATAL 0x3
+#define MUM_EVENT_DATA_OFST 0
+#define MUM_EVENT_SENSOR_ID_LBN 0
+#define MUM_EVENT_SENSOR_ID_WIDTH 8
+/* Enum values, see field(s): */
+/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */
+#define MUM_EVENT_SENSOR_STATE_LBN 8
+#define MUM_EVENT_SENSOR_STATE_WIDTH 8
+#define MUM_EVENT_PORT_PHY_READY_LBN 0
+#define MUM_EVENT_PORT_PHY_READY_WIDTH 1
+#define MUM_EVENT_PORT_PHY_LINK_UP_LBN 1
+#define MUM_EVENT_PORT_PHY_LINK_UP_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_LOL_LBN 2
+#define MUM_EVENT_PORT_PHY_TX_LOL_WIDTH 1
+#define MUM_EVENT_PORT_PHY_RX_LOL_LBN 3
+#define MUM_EVENT_PORT_PHY_RX_LOL_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_LOS_LBN 4
+#define MUM_EVENT_PORT_PHY_TX_LOS_WIDTH 1
+#define MUM_EVENT_PORT_PHY_RX_LOS_LBN 5
+#define MUM_EVENT_PORT_PHY_RX_LOS_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_FAULT_LBN 6
+#define MUM_EVENT_PORT_PHY_TX_FAULT_WIDTH 1
+#define MUM_EVENT_DATA_LBN 0
+#define MUM_EVENT_DATA_WIDTH 32
+#define MUM_EVENT_SRC_LBN 36
+#define MUM_EVENT_SRC_WIDTH 8
+#define MUM_EVENT_EV_CODE_LBN 60
+#define MUM_EVENT_EV_CODE_WIDTH 4
+#define MUM_EVENT_CODE_LBN 44
+#define MUM_EVENT_CODE_WIDTH 8
+/* enum: The MUM was rebooted. */
+#define MUM_EVENT_CODE_REBOOT 0x1
+/* enum: Bad assert. */
+#define MUM_EVENT_CODE_ASSERT 0x2
+/* enum: Sensor failure. */
+#define MUM_EVENT_CODE_SENSOR 0x3
+/* enum: Link fault has been asserted, or has cleared. */
+#define MUM_EVENT_CODE_QSFP_LASI_INTERRUPT 0x4
+#define MUM_EVENT_SENSOR_DATA_OFST 0
+#define MUM_EVENT_SENSOR_DATA_LBN 0
+#define MUM_EVENT_SENSOR_DATA_WIDTH 32
+#define MUM_EVENT_PORT_PHY_FLAGS_OFST 0
+#define MUM_EVENT_PORT_PHY_FLAGS_LBN 0
+#define MUM_EVENT_PORT_PHY_FLAGS_WIDTH 32
+#define MUM_EVENT_PORT_PHY_COPPER_LEN_OFST 0
+#define MUM_EVENT_PORT_PHY_COPPER_LEN_LBN 0
+#define MUM_EVENT_PORT_PHY_COPPER_LEN_WIDTH 32
+#define MUM_EVENT_PORT_PHY_CAPS_OFST 0
+#define MUM_EVENT_PORT_PHY_CAPS_LBN 0
+#define MUM_EVENT_PORT_PHY_CAPS_WIDTH 32
+#define MUM_EVENT_PORT_PHY_TECH_OFST 0
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_UNKNOWN 0x0 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_OPTICAL 0x1 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_PASSIVE 0x2 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_PASSIVE_EQUALIZED 0x3 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_ACTIVE_LIMITING 0x4 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_ACTIVE_LINEAR 0x5 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_BASE_T 0x6 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_LOOPBACK_PASSIVE 0x7 /* enum */
+#define MUM_EVENT_PORT_PHY_TECH_LBN 0
+#define MUM_EVENT_PORT_PHY_TECH_WIDTH 32
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_LBN 36
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_WIDTH 4
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_FLAGS 0x0 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_COPPER_LEN 0x1 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_CAPS 0x2 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_TECH 0x3 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_MAX 0x4 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_PORT_NO_LBN 40
+#define MUM_EVENT_PORT_PHY_SRC_PORT_NO_WIDTH 4
+
/***********************************/
/* MC_CMD_READ32
* Read multiple 32byte words from MC memory.
*/
#define MC_CMD_READ32 0x1
+#undef MC_CMD_0x1_PRIVILEGE_CTG
+
+#define MC_CMD_0x1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_READ32_IN msgrequest */
#define MC_CMD_READ32_IN_LEN 8
@@ -480,6 +893,9 @@
* Write multiple 32byte words to MC memory.
*/
#define MC_CMD_WRITE32 0x2
+#undef MC_CMD_0x2_PRIVILEGE_CTG
+
+#define MC_CMD_0x2_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_WRITE32_IN msgrequest */
#define MC_CMD_WRITE32_IN_LENMIN 8
@@ -500,26 +916,64 @@
* Copy MC code between two locations and jump.
*/
#define MC_CMD_COPYCODE 0x3
+#undef MC_CMD_0x3_PRIVILEGE_CTG
+
+#define MC_CMD_0x3_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_COPYCODE_IN msgrequest */
#define MC_CMD_COPYCODE_IN_LEN 16
+/* Source address
+ *
+ * The main image should be entered via a copy of a single word from and to a
+ * magic address, which controls various aspects of the boot. The magic address
+ * is a bitfield, with each bit as documented below.
+ */
#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0
+/* enum: Deprecated; equivalent to setting BOOT_MAGIC_PRESENT (see below) */
+#define MC_CMD_COPYCODE_HUNT_NO_MAGIC_ADDR 0x10000
+/* enum: Deprecated; equivalent to setting BOOT_MAGIC_PRESENT and
+ * BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED (see below)
+ */
+#define MC_CMD_COPYCODE_HUNT_NO_DATAPATH_MAGIC_ADDR 0x1d0d0
+/* enum: Deprecated; equivalent to setting BOOT_MAGIC_PRESENT,
+ * BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED and BOOT_MAGIC_IGNORE_CONFIG (see
+ * below)
+ */
+#define MC_CMD_COPYCODE_HUNT_IGNORE_CONFIG_MAGIC_ADDR 0x1badc
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_PRESENT_LBN 17
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_PRESENT_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED_LBN 2
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_IGNORE_CONFIG_LBN 3
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_IGNORE_CONFIG_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SKIP_BOOT_ICORE_SYNC_LBN 4
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SKIP_BOOT_ICORE_SYNC_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_FORCE_STANDALONE_LBN 5
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_FORCE_STANDALONE_WIDTH 1
+/* Destination address */
#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4
#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8
+/* Address of where to jump after copy. */
#define MC_CMD_COPYCODE_IN_JUMP_OFST 12
-#define MC_CMD_COPYCODE_JUMP_NONE 0x1 /* enum */
+/* enum: Control should return to the caller rather than jumping */
+#define MC_CMD_COPYCODE_JUMP_NONE 0x1
/* MC_CMD_COPYCODE_OUT msgresponse */
#define MC_CMD_COPYCODE_OUT_LEN 0
/***********************************/
-/* MC_CMD_SET_FUNC
+/* MC_CMD_SET_FUNC
+ * Select function for function-specific commands.
*/
-#define MC_CMD_SET_FUNC 0x4
+#define MC_CMD_SET_FUNC 0x4
+#undef MC_CMD_0x4_PRIVILEGE_CTG
+
+#define MC_CMD_0x4_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_FUNC_IN msgrequest */
#define MC_CMD_SET_FUNC_IN_LEN 4
+/* Set function */
#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0
/* MC_CMD_SET_FUNC_OUT msgresponse */
@@ -528,15 +982,22 @@
/***********************************/
/* MC_CMD_GET_BOOT_STATUS
+ * Get the instruction address from which the MC booted.
*/
#define MC_CMD_GET_BOOT_STATUS 0x5
+#undef MC_CMD_0x5_PRIVILEGE_CTG
+
+#define MC_CMD_0x5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_GET_BOOT_STATUS_IN msgrequest */
#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0
/* MC_CMD_GET_BOOT_STATUS_OUT msgresponse */
#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8
+/* ?? */
#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0
+/* enum: indicates that the MC wasn't flash booted */
+#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_NULL 0xdeadbeef
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_WIDTH 1
@@ -547,41 +1008,69 @@
/***********************************/
-/* MC_CMD_GET_ASSERTS
- * Get and clear any assertion status.
+/* MC_CMD_GET_ASSERTS
+ * Get (and optionally clear) the current assertion status. Only
+ * OUT.GLOBAL_FLAGS is guaranteed to exist in the completion payload. The other
+ * fields will only be present if OUT.GLOBAL_FLAGS != NO_FAILS
*/
-#define MC_CMD_GET_ASSERTS 0x6
+#define MC_CMD_GET_ASSERTS 0x6
+#undef MC_CMD_0x6_PRIVILEGE_CTG
+
+#define MC_CMD_0x6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_GET_ASSERTS_IN msgrequest */
#define MC_CMD_GET_ASSERTS_IN_LEN 4
+/* Set to clear assertion */
#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0
/* MC_CMD_GET_ASSERTS_OUT msgresponse */
#define MC_CMD_GET_ASSERTS_OUT_LEN 140
+/* Assertion status flag. */
#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0
-#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 /* enum */
-#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2 /* enum */
-#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3 /* enum */
-#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4 /* enum */
+/* enum: No assertions have failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1
+/* enum: A system-level assertion has failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2
+/* enum: A thread-level assertion has failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3
+/* enum: The system was reset by the watchdog. */
+#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4
+/* enum: An illegal address trap stopped the system (huntington and later) */
+#define MC_CMD_GET_ASSERTS_FLAGS_ADDR_TRAP 0x5
+/* Failing PC value */
#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4
+/* Saved GP regs */
#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8
#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_LEN 4
#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM 31
+/* enum: A magic value hinting that the value in this register at the time of
+ * the failure has likely been lost.
+ */
+#define MC_CMD_GET_ASSERTS_REG_NO_DATA 0xda7a1057
+/* Failing thread address */
#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132
#define MC_CMD_GET_ASSERTS_OUT_RESERVED_OFST 136
/***********************************/
-/* MC_CMD_LOG_CTRL
- * Configure the output stream for various events and messages.
+/* MC_CMD_LOG_CTRL
+ * Configure the output stream for log events such as link state changes,
+ * sensor notifications and MCDI completions
*/
-#define MC_CMD_LOG_CTRL 0x7
+#define MC_CMD_LOG_CTRL 0x7
+#undef MC_CMD_0x7_PRIVILEGE_CTG
+
+#define MC_CMD_0x7_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_LOG_CTRL_IN msgrequest */
#define MC_CMD_LOG_CTRL_IN_LEN 8
+/* Log destination */
#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0
-#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1 /* enum */
-#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2 /* enum */
+/* enum: UART. */
+#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1
+/* enum: Event queue. */
+#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2
+/* Legacy argument. Must be zero. */
#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4
/* MC_CMD_LOG_CTRL_OUT msgresponse */
@@ -589,21 +1078,31 @@
/***********************************/
-/* MC_CMD_GET_VERSION
+/* MC_CMD_GET_VERSION
* Get version information about the MC firmware.
*/
-#define MC_CMD_GET_VERSION 0x8
+#define MC_CMD_GET_VERSION 0x8
+#undef MC_CMD_0x8_PRIVILEGE_CTG
+
+#define MC_CMD_0x8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_VERSION_IN msgrequest */
#define MC_CMD_GET_VERSION_IN_LEN 0
-/* MC_CMD_GET_VERSION_V0_OUT msgresponse */
+/* MC_CMD_GET_VERSION_EXT_IN msgrequest: Asks for the extended version */
+#define MC_CMD_GET_VERSION_EXT_IN_LEN 4
+/* placeholder, set to 0 */
+#define MC_CMD_GET_VERSION_EXT_IN_EXT_FLAGS_OFST 0
+
+/* MC_CMD_GET_VERSION_V0_OUT msgresponse: deprecated version format */
#define MC_CMD_GET_VERSION_V0_OUT_LEN 4
#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff /* enum */
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000 /* enum */
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_SIENA_BOOTROM 0xb0070000 /* enum */
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_HUNT_BOOTROM 0xb0070001 /* enum */
+/* enum: Reserved version number to indicate "any" version. */
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff
+/* enum: Bootrom version value for Siena. */
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_SIENA_BOOTROM 0xb0070000
+/* enum: Bootrom version value for Huntington. */
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_HUNT_BOOTROM 0xb0070001
/* MC_CMD_GET_VERSION_OUT msgresponse */
#define MC_CMD_GET_VERSION_OUT_LEN 32
@@ -611,6 +1110,7 @@
/* Enum values, see field(s): */
/* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */
#define MC_CMD_GET_VERSION_OUT_PCOL_OFST 4
+/* 128bit mask of functions supported by the current firmware */
#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_OFST 8
#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_LEN 16
#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24
@@ -618,77 +1118,187 @@
#define MC_CMD_GET_VERSION_OUT_VERSION_LO_OFST 24
#define MC_CMD_GET_VERSION_OUT_VERSION_HI_OFST 28
+/* MC_CMD_GET_VERSION_EXT_OUT msgresponse */
+#define MC_CMD_GET_VERSION_EXT_OUT_LEN 48
+/* MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */
+/* Enum values, see field(s): */
+/* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */
+#define MC_CMD_GET_VERSION_EXT_OUT_PCOL_OFST 4
+/* 128bit mask of functions supported by the current firmware */
+#define MC_CMD_GET_VERSION_EXT_OUT_SUPPORTED_FUNCS_OFST 8
+#define MC_CMD_GET_VERSION_EXT_OUT_SUPPORTED_FUNCS_LEN 16
+#define MC_CMD_GET_VERSION_EXT_OUT_VERSION_OFST 24
+#define MC_CMD_GET_VERSION_EXT_OUT_VERSION_LEN 8
+#define MC_CMD_GET_VERSION_EXT_OUT_VERSION_LO_OFST 24
+#define MC_CMD_GET_VERSION_EXT_OUT_VERSION_HI_OFST 28
+/* extra info */
+#define MC_CMD_GET_VERSION_EXT_OUT_EXTRA_OFST 32
+#define MC_CMD_GET_VERSION_EXT_OUT_EXTRA_LEN 16
+
/***********************************/
-/* MC_CMD_FC
+/* MC_CMD_FC
* Perform an FC operation
*/
-#define MC_CMD_FC 0x9
+#define MC_CMD_FC 0x9
/* MC_CMD_FC_IN msgrequest */
#define MC_CMD_FC_IN_LEN 4
#define MC_CMD_FC_IN_OP_HDR_OFST 0
#define MC_CMD_FC_IN_OP_LBN 0
#define MC_CMD_FC_IN_OP_WIDTH 8
-#define MC_CMD_FC_OP_NULL 0x1 /* enum */
-#define MC_CMD_FC_OP_UNUSED 0x2 /* enum */
-#define MC_CMD_FC_OP_MAC 0x3 /* enum */
-#define MC_CMD_FC_OP_READ32 0x4 /* enum */
-#define MC_CMD_FC_OP_WRITE32 0x5 /* enum */
-#define MC_CMD_FC_OP_TRC_READ 0x6 /* enum */
-#define MC_CMD_FC_OP_TRC_WRITE 0x7 /* enum */
-#define MC_CMD_FC_OP_GET_VERSION 0x8 /* enum */
-#define MC_CMD_FC_OP_TRC_RX_READ 0x9 /* enum */
-#define MC_CMD_FC_OP_TRC_RX_WRITE 0xa /* enum */
-#define MC_CMD_FC_OP_SFP 0xb /* enum */
-#define MC_CMD_FC_OP_DDR_TEST 0xc /* enum */
-#define MC_CMD_FC_OP_GET_ASSERT 0xd /* enum */
-#define MC_CMD_FC_OP_FPGA_BUILD 0xe /* enum */
-#define MC_CMD_FC_OP_READ_MAP 0xf /* enum */
-#define MC_CMD_FC_OP_CAPABILITIES 0x10 /* enum */
-#define MC_CMD_FC_OP_GLOBAL_FLAGS 0x11 /* enum */
-#define MC_CMD_FC_OP_IO_REL 0x12 /* enum */
-#define MC_CMD_FC_OP_UHLINK 0x13 /* enum */
-#define MC_CMD_FC_OP_SET_LINK 0x14 /* enum */
-#define MC_CMD_FC_OP_LICENSE 0x15 /* enum */
-#define MC_CMD_FC_OP_STARTUP 0x16 /* enum */
-#define MC_CMD_FC_OP_DMA 0x17 /* enum */
-#define MC_CMD_FC_OP_TIMED_READ 0x18 /* enum */
-#define MC_CMD_FC_OP_LOG 0x19 /* enum */
-#define MC_CMD_FC_OP_CLOCK 0x1a /* enum */
-#define MC_CMD_FC_OP_DDR 0x1b /* enum */
-#define MC_CMD_FC_OP_TIMESTAMP 0x1c /* enum */
-#define MC_CMD_FC_OP_SPI 0x1d /* enum */
-#define MC_CMD_FC_OP_DIAG 0x1e /* enum */
-#define MC_CMD_FC_IN_PORT_EXT_OFST 0x0 /* enum */
-#define MC_CMD_FC_IN_PORT_INT_OFST 0x40 /* enum */
+/* enum: NULL MCDI command to FC. */
+#define MC_CMD_FC_OP_NULL 0x1
+/* enum: Unused opcode */
+#define MC_CMD_FC_OP_UNUSED 0x2
+/* enum: MAC driver commands */
+#define MC_CMD_FC_OP_MAC 0x3
+/* enum: Read FC memory */
+#define MC_CMD_FC_OP_READ32 0x4
+/* enum: Write to FC memory */
+#define MC_CMD_FC_OP_WRITE32 0x5
+/* enum: Read FC memory */
+#define MC_CMD_FC_OP_TRC_READ 0x6
+/* enum: Write to FC memory */
+#define MC_CMD_FC_OP_TRC_WRITE 0x7
+/* enum: FC firmware Version */
+#define MC_CMD_FC_OP_GET_VERSION 0x8
+/* enum: Read FC memory */
+#define MC_CMD_FC_OP_TRC_RX_READ 0x9
+/* enum: Write to FC memory */
+#define MC_CMD_FC_OP_TRC_RX_WRITE 0xa
+/* enum: SFP parameters */
+#define MC_CMD_FC_OP_SFP 0xb
+/* enum: DDR3 test */
+#define MC_CMD_FC_OP_DDR_TEST 0xc
+/* enum: Get Crash context from FC */
+#define MC_CMD_FC_OP_GET_ASSERT 0xd
+/* enum: Get FPGA Build registers */
+#define MC_CMD_FC_OP_FPGA_BUILD 0xe
+/* enum: Read map support commands */
+#define MC_CMD_FC_OP_READ_MAP 0xf
+/* enum: FC Capabilities */
+#define MC_CMD_FC_OP_CAPABILITIES 0x10
+/* enum: FC Global flags */
+#define MC_CMD_FC_OP_GLOBAL_FLAGS 0x11
+/* enum: FC IO using relative addressing modes */
+#define MC_CMD_FC_OP_IO_REL 0x12
+/* enum: FPGA link information */
+#define MC_CMD_FC_OP_UHLINK 0x13
+/* enum: Configure loopbacks and link on FPGA ports */
+#define MC_CMD_FC_OP_SET_LINK 0x14
+/* enum: Licensing operations relating to AOE */
+#define MC_CMD_FC_OP_LICENSE 0x15
+/* enum: Startup information to the FC */
+#define MC_CMD_FC_OP_STARTUP 0x16
+/* enum: Configure a DMA read */
+#define MC_CMD_FC_OP_DMA 0x17
+/* enum: Configure a timed read */
+#define MC_CMD_FC_OP_TIMED_READ 0x18
+/* enum: Control UART logging */
+#define MC_CMD_FC_OP_LOG 0x19
+/* enum: Get the value of a given clock_id */
+#define MC_CMD_FC_OP_CLOCK 0x1a
+/* enum: DDR3/QDR3 parameters */
+#define MC_CMD_FC_OP_DDR 0x1b
+/* enum: PTP and timestamp control */
+#define MC_CMD_FC_OP_TIMESTAMP 0x1c
+/* enum: Commands for SPI Flash interface */
+#define MC_CMD_FC_OP_SPI 0x1d
+/* enum: Commands for diagnostic components */
+#define MC_CMD_FC_OP_DIAG 0x1e
+/* enum: External AOE port. */
+#define MC_CMD_FC_IN_PORT_EXT_OFST 0x0
+/* enum: Internal AOE port. */
+#define MC_CMD_FC_IN_PORT_INT_OFST 0x40
/* MC_CMD_FC_IN_NULL msgrequest */
#define MC_CMD_FC_IN_NULL_LEN 4
#define MC_CMD_FC_IN_CMD_OFST 0
+/* MC_CMD_FC_IN_PHY msgrequest */
+#define MC_CMD_FC_IN_PHY_LEN 5
+/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* FC PHY driver operation code */
+#define MC_CMD_FC_IN_PHY_OP_OFST 4
+#define MC_CMD_FC_IN_PHY_OP_LEN 1
+/* enum: PHY init handler */
+#define MC_CMD_FC_OP_PHY_OP_INIT 0x1
+/* enum: PHY reconfigure handler */
+#define MC_CMD_FC_OP_PHY_OP_RECONFIGURE 0x2
+/* enum: PHY reboot handler */
+#define MC_CMD_FC_OP_PHY_OP_REBOOT 0x3
+/* enum: PHY get_supported_cap handler */
+#define MC_CMD_FC_OP_PHY_OP_GET_SUPPORTED_CAP 0x4
+/* enum: PHY get_config handler */
+#define MC_CMD_FC_OP_PHY_OP_GET_CONFIG 0x5
+/* enum: PHY get_media_info handler */
+#define MC_CMD_FC_OP_PHY_OP_GET_MEDIA_INFO 0x6
+/* enum: PHY set_led handler */
+#define MC_CMD_FC_OP_PHY_OP_SET_LED 0x7
+/* enum: PHY lasi_interrupt handler */
+#define MC_CMD_FC_OP_PHY_OP_LASI_INTERRUPT 0x8
+/* enum: PHY check_link handler */
+#define MC_CMD_FC_OP_PHY_OP_CHECK_LINK 0x9
+/* enum: PHY fill_stats handler */
+#define MC_CMD_FC_OP_PHY_OP_FILL_STATS 0xa
+/* enum: PHY bpx_link_state_changed handler */
+#define MC_CMD_FC_OP_PHY_OP_BPX_LINK_STATE_CHANGED 0xb
+/* enum: PHY get_state handler */
+#define MC_CMD_FC_OP_PHY_OP_GET_STATE 0xc
+/* enum: PHY start_bist handler */
+#define MC_CMD_FC_OP_PHY_OP_START_BIST 0xd
+/* enum: PHY poll_bist handler */
+#define MC_CMD_FC_OP_PHY_OP_POLL_BIST 0xe
+/* enum: PHY nvram_test handler */
+#define MC_CMD_FC_OP_PHY_OP_NVRAM_TEST 0xf
+/* enum: PHY relinquish handler */
+#define MC_CMD_FC_OP_PHY_OP_RELINQUISH_SPI 0x10
+/* enum: PHY read connection from FC - may be not required */
+#define MC_CMD_FC_OP_PHY_OP_GET_CONNECTION 0x11
+/* enum: PHY read flags from FC - may be not required */
+#define MC_CMD_FC_OP_PHY_OP_GET_FLAGS 0x12
+
+/* MC_CMD_FC_IN_PHY_INIT msgrequest */
+#define MC_CMD_FC_IN_PHY_INIT_LEN 4
+#define MC_CMD_FC_IN_PHY_CMD_OFST 0
+
/* MC_CMD_FC_IN_MAC msgrequest */
#define MC_CMD_FC_IN_MAC_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_MAC_HEADER_OFST 4
#define MC_CMD_FC_IN_MAC_OP_LBN 0
#define MC_CMD_FC_IN_MAC_OP_WIDTH 8
-#define MC_CMD_FC_OP_MAC_OP_RECONFIGURE 0x1 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_SET_LINK 0x2 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_GET_STATS 0x3 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_GET_RX_STATS 0x6 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_GET_TX_STATS 0x7 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_READ_STATUS 0x8 /* enum */
+/* enum: MAC reconfigure handler */
+#define MC_CMD_FC_OP_MAC_OP_RECONFIGURE 0x1
+/* enum: MAC Set command - same as MC_CMD_SET_MAC */
+#define MC_CMD_FC_OP_MAC_OP_SET_LINK 0x2
+/* enum: MAC statistics */
+#define MC_CMD_FC_OP_MAC_OP_GET_STATS 0x3
+/* enum: MAC RX statistics */
+#define MC_CMD_FC_OP_MAC_OP_GET_RX_STATS 0x6
+/* enum: MAC TX statistics */
+#define MC_CMD_FC_OP_MAC_OP_GET_TX_STATS 0x7
+/* enum: MAC Read status */
+#define MC_CMD_FC_OP_MAC_OP_READ_STATUS 0x8
#define MC_CMD_FC_IN_MAC_PORT_TYPE_LBN 8
#define MC_CMD_FC_IN_MAC_PORT_TYPE_WIDTH 8
-#define MC_CMD_FC_PORT_EXT 0x0 /* enum */
-#define MC_CMD_FC_PORT_INT 0x1 /* enum */
+/* enum: External FPGA port. */
+#define MC_CMD_FC_PORT_EXT 0x0
+/* enum: Internal Siena-facing FPGA ports. */
+#define MC_CMD_FC_PORT_INT 0x1
#define MC_CMD_FC_IN_MAC_PORT_IDX_LBN 16
#define MC_CMD_FC_IN_MAC_PORT_IDX_WIDTH 8
#define MC_CMD_FC_IN_MAC_CMD_FORMAT_LBN 24
#define MC_CMD_FC_IN_MAC_CMD_FORMAT_WIDTH 8
-#define MC_CMD_FC_OP_MAC_CMD_FORMAT_DEFAULT 0x0 /* enum */
-#define MC_CMD_FC_OP_MAC_CMD_FORMAT_PORT_OVERRIDE 0x1 /* enum */
+/* enum: Default FC command format; the fields PORT_TYPE and PORT_IDX are
+ * irrelevant. Port number is derived from pci_fn; passed in FC header.
+ */
+#define MC_CMD_FC_OP_MAC_CMD_FORMAT_DEFAULT 0x0
+/* enum: Override default port number. Port number determined by fields
+ * PORT_TYPE and PORT_IDX.
+ */
+#define MC_CMD_FC_OP_MAC_CMD_FORMAT_PORT_OVERRIDE 0x1
/* MC_CMD_FC_IN_MAC_RECONFIGURE msgrequest */
#define MC_CMD_FC_IN_MAC_RECONFIGURE_LEN 8
@@ -699,7 +1309,9 @@
#define MC_CMD_FC_IN_MAC_SET_LINK_LEN 32
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_MAC_HEADER_OFST 4 */
+/* MTU size */
#define MC_CMD_FC_IN_MAC_SET_LINK_MTU_OFST 8
+/* Drain Tx FIFO */
#define MC_CMD_FC_IN_MAC_SET_LINK_DRAIN_OFST 12
#define MC_CMD_FC_IN_MAC_SET_LINK_ADDR_OFST 16
#define MC_CMD_FC_IN_MAC_SET_LINK_ADDR_LEN 8
@@ -731,6 +1343,7 @@
#define MC_CMD_FC_IN_MAC_GET_STATS_LEN 20
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_MAC_HEADER_OFST 4 */
+/* MC Statistics index */
#define MC_CMD_FC_IN_MAC_GET_STATS_STATS_INDEX_OFST 8
#define MC_CMD_FC_IN_MAC_GET_STATS_FLAGS_OFST 12
#define MC_CMD_FC_IN_MAC_GET_STATS_CLEAR_ALL_LBN 0
@@ -739,6 +1352,7 @@
#define MC_CMD_FC_IN_MAC_GET_STATS_CLEAR_WIDTH 1
#define MC_CMD_FC_IN_MAC_GET_STATS_UPDATE_LBN 2
#define MC_CMD_FC_IN_MAC_GET_STATS_UPDATE_WIDTH 1
+/* Number of statistics to read */
#define MC_CMD_FC_IN_MAC_GET_STATS_NUM_OFST 16
#define MC_CMD_FC_MAC_NSTATS_PER_BLOCK 0x1e /* enum */
#define MC_CMD_FC_MAC_NBYTES_PER_STAT 0x8 /* enum */
@@ -797,13 +1411,24 @@
#define MC_CMD_FC_IN_TRC_RX_WRITE_DATA_NUM 2
/* MC_CMD_FC_IN_SFP msgrequest */
-#define MC_CMD_FC_IN_SFP_LEN 24
+#define MC_CMD_FC_IN_SFP_LEN 28
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* Link speed is 100, 1000, 10000, 40000 */
#define MC_CMD_FC_IN_SFP_SPEED_OFST 4
+/* Length of copper cable - zero when not relevant (e.g. if cable is fibre) */
#define MC_CMD_FC_IN_SFP_COPPER_LEN_OFST 8
+/* Not relevant for cards with QSFP modules. For older cards, true if module is
+ * a dual speed SFP+ module.
+ */
#define MC_CMD_FC_IN_SFP_DUAL_SPEED_OFST 12
+/* True if an SFP Module is present (other fields valid when true) */
#define MC_CMD_FC_IN_SFP_PRESENT_OFST 16
+/* The type of the SFP+ Module. For later cards with QSFP modules, this field
+ * is unused and the type is communicated by other means.
+ */
#define MC_CMD_FC_IN_SFP_TYPE_OFST 20
+/* Capabilities corresponding to 1 bits. */
+#define MC_CMD_FC_IN_SFP_CAPS_OFST 24
/* MC_CMD_FC_IN_DDR_TEST msgrequest */
#define MC_CMD_FC_IN_DDR_TEST_LEN 8
@@ -811,8 +1436,10 @@
#define MC_CMD_FC_IN_DDR_TEST_HEADER_OFST 4
#define MC_CMD_FC_IN_DDR_TEST_OP_LBN 0
#define MC_CMD_FC_IN_DDR_TEST_OP_WIDTH 8
-#define MC_CMD_FC_OP_DDR_TEST_START 0x1 /* enum */
-#define MC_CMD_FC_OP_DDR_TEST_POLL 0x2 /* enum */
+/* enum: DRAM Test Start */
+#define MC_CMD_FC_OP_DDR_TEST_START 0x1
+/* enum: DRAM Test Poll */
+#define MC_CMD_FC_OP_DDR_TEST_POLL 0x2
/* MC_CMD_FC_IN_DDR_TEST_START msgrequest */
#define MC_CMD_FC_IN_DDR_TEST_START_LEN 12
@@ -840,10 +1467,14 @@
/* MC_CMD_FC_IN_FPGA_BUILD msgrequest */
#define MC_CMD_FC_IN_FPGA_BUILD_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* FPGA build info operation code */
#define MC_CMD_FC_IN_FPGA_BUILD_OP_OFST 4
-#define MC_CMD_FC_IN_FPGA_BUILD_BUILD 0x1 /* enum */
-#define MC_CMD_FC_IN_FPGA_BUILD_SERVICES 0x2 /* enum */
-#define MC_CMD_FC_IN_FPGA_BUILD_BSP_VERSION 0x3 /* enum */
+/* enum: Get the build registers */
+#define MC_CMD_FC_IN_FPGA_BUILD_BUILD 0x1
+/* enum: Get the services registers */
+#define MC_CMD_FC_IN_FPGA_BUILD_SERVICES 0x2
+/* enum: Get the BSP version */
+#define MC_CMD_FC_IN_FPGA_BUILD_BSP_VERSION 0x3
/* MC_CMD_FC_IN_READ_MAP msgrequest */
#define MC_CMD_FC_IN_READ_MAP_LEN 8
@@ -851,8 +1482,10 @@
#define MC_CMD_FC_IN_READ_MAP_HEADER_OFST 4
#define MC_CMD_FC_IN_READ_MAP_OP_LBN 0
#define MC_CMD_FC_IN_READ_MAP_OP_WIDTH 8
-#define MC_CMD_FC_OP_READ_MAP_COUNT 0x1 /* enum */
-#define MC_CMD_FC_OP_READ_MAP_INDEX 0x2 /* enum */
+/* enum: Get the number of map regions */
+#define MC_CMD_FC_OP_READ_MAP_COUNT 0x1
+/* enum: Get the specified map */
+#define MC_CMD_FC_OP_READ_MAP_INDEX 0x2
/* MC_CMD_FC_IN_READ_MAP_COUNT msgrequest */
#define MC_CMD_FC_IN_READ_MAP_COUNT_LEN 8
@@ -892,13 +1525,18 @@
#define MC_CMD_FC_IN_IO_REL_HEADER_OFST 4
#define MC_CMD_FC_IN_IO_REL_OP_LBN 0
#define MC_CMD_FC_IN_IO_REL_OP_WIDTH 8
-#define MC_CMD_FC_IN_IO_REL_GET_ADDR 0x1 /* enum */
-#define MC_CMD_FC_IN_IO_REL_READ32 0x2 /* enum */
-#define MC_CMD_FC_IN_IO_REL_WRITE32 0x3 /* enum */
+/* enum: Get the base address that the FC applies to relative commands */
+#define MC_CMD_FC_IN_IO_REL_GET_ADDR 0x1
+/* enum: Read data */
+#define MC_CMD_FC_IN_IO_REL_READ32 0x2
+/* enum: Write data */
+#define MC_CMD_FC_IN_IO_REL_WRITE32 0x3
#define MC_CMD_FC_IN_IO_REL_COMP_TYPE_LBN 8
#define MC_CMD_FC_IN_IO_REL_COMP_TYPE_WIDTH 8
-#define MC_CMD_FC_COMP_TYPE_APP_ADDR_SPACE 0x1 /* enum */
-#define MC_CMD_FC_COMP_TYPE_FLASH 0x2 /* enum */
+/* enum: Application address space */
+#define MC_CMD_FC_COMP_TYPE_APP_ADDR_SPACE 0x1
+/* enum: Flash address space */
+#define MC_CMD_FC_COMP_TYPE_FLASH 0x2
/* MC_CMD_FC_IN_IO_REL_GET_ADDR msgrequest */
#define MC_CMD_FC_IN_IO_REL_GET_ADDR_LEN 8
@@ -932,22 +1570,36 @@
#define MC_CMD_FC_IN_UHLINK_HEADER_OFST 4
#define MC_CMD_FC_IN_UHLINK_OP_LBN 0
#define MC_CMD_FC_IN_UHLINK_OP_WIDTH 8
-#define MC_CMD_FC_OP_UHLINK_PHY 0x1 /* enum */
-#define MC_CMD_FC_OP_UHLINK_MAC 0x2 /* enum */
-#define MC_CMD_FC_OP_UHLINK_RX_EYE 0x3 /* enum */
-#define MC_CMD_FC_OP_UHLINK_DUMP_RX_EYE_PLOT 0x4 /* enum */
-#define MC_CMD_FC_OP_UHLINK_READ_RX_EYE_PLOT 0x5 /* enum */
-#define MC_CMD_FC_OP_UHLINK_RX_TUNE 0x6 /* enum */
-#define MC_CMD_FC_OP_UHLINK_LOOPBACK_SET 0x7 /* enum */
-#define MC_CMD_FC_OP_UHLINK_LOOPBACK_GET 0x8 /* enum */
+/* enum: Get PHY configuration info */
+#define MC_CMD_FC_OP_UHLINK_PHY 0x1
+/* enum: Get MAC configuration info */
+#define MC_CMD_FC_OP_UHLINK_MAC 0x2
+/* enum: Get Rx eye table */
+#define MC_CMD_FC_OP_UHLINK_RX_EYE 0x3
+/* enum: Get Rx eye plot */
+#define MC_CMD_FC_OP_UHLINK_DUMP_RX_EYE_PLOT 0x4
+/* enum: Get Rx eye plot */
+#define MC_CMD_FC_OP_UHLINK_READ_RX_EYE_PLOT 0x5
+/* enum: Retune Rx settings */
+#define MC_CMD_FC_OP_UHLINK_RX_TUNE 0x6
+/* enum: Set loopback mode on fpga port */
+#define MC_CMD_FC_OP_UHLINK_LOOPBACK_SET 0x7
+/* enum: Get loopback mode config state on fpga port */
+#define MC_CMD_FC_OP_UHLINK_LOOPBACK_GET 0x8
#define MC_CMD_FC_IN_UHLINK_PORT_TYPE_LBN 8
#define MC_CMD_FC_IN_UHLINK_PORT_TYPE_WIDTH 8
#define MC_CMD_FC_IN_UHLINK_PORT_IDX_LBN 16
#define MC_CMD_FC_IN_UHLINK_PORT_IDX_WIDTH 8
#define MC_CMD_FC_IN_UHLINK_CMD_FORMAT_LBN 24
#define MC_CMD_FC_IN_UHLINK_CMD_FORMAT_WIDTH 8
-#define MC_CMD_FC_OP_UHLINK_CMD_FORMAT_DEFAULT 0x0 /* enum */
-#define MC_CMD_FC_OP_UHLINK_CMD_FORMAT_PORT_OVERRIDE 0x1 /* enum */
+/* enum: Default FC command format; the fields PORT_TYPE and PORT_IDX are
+ * irrelevant. Port number is derived from pci_fn; passed in FC header.
+ */
+#define MC_CMD_FC_OP_UHLINK_CMD_FORMAT_DEFAULT 0x0
+/* enum: Override default port number. Port number determined by fields
+ * PORT_TYPE and PORT_IDX.
+ */
+#define MC_CMD_FC_OP_UHLINK_CMD_FORMAT_PORT_OVERRIDE 0x1
/* MC_CMD_FC_OP_UHLINK_PHY msgrequest */
#define MC_CMD_FC_OP_UHLINK_PHY_LEN 8
@@ -1006,6 +1658,7 @@
/* MC_CMD_FC_IN_SET_LINK msgrequest */
#define MC_CMD_FC_IN_SET_LINK_LEN 16
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* See MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
#define MC_CMD_FC_IN_SET_LINK_MODE_OFST 4
#define MC_CMD_FC_IN_SET_LINK_SPEED_OFST 8
#define MC_CMD_FC_IN_SET_LINK_FLAGS_OFST 12
@@ -1028,7 +1681,9 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_STARTUP_BASE_OFST 4
#define MC_CMD_FC_IN_STARTUP_LENGTH_OFST 8
+/* Length of identifier */
#define MC_CMD_FC_IN_STARTUP_IDLENGTH_OFST 12
+/* Identifier for AOE FPGA */
#define MC_CMD_FC_IN_STARTUP_ID_OFST 16
#define MC_CMD_FC_IN_STARTUP_ID_LEN 1
#define MC_CMD_FC_IN_STARTUP_ID_NUM 24
@@ -1044,6 +1699,7 @@
#define MC_CMD_FC_IN_DMA_STOP_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_DMA_OP_OFST 4 */
+/* FC supplied handle */
#define MC_CMD_FC_IN_DMA_STOP_FC_HANDLE_OFST 8
/* MC_CMD_FC_IN_DMA_READ msgrequest */
@@ -1065,18 +1721,25 @@
#define MC_CMD_FC_IN_TIMED_READ_SET_LEN 52
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_TIMED_READ_OP_OFST 4 */
+/* Host supplied handle (unique) */
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_HANDLE_OFST 8
+/* Address into which to transfer data in host */
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_DMA_ADDRESS_OFST 12
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_DMA_ADDRESS_LEN 8
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_DMA_ADDRESS_LO_OFST 12
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_DMA_ADDRESS_HI_OFST 16
+/* AOE address from which to transfer data */
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_ADDRESS_OFST 20
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_ADDRESS_LEN 8
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_ADDRESS_LO_OFST 20
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_ADDRESS_HI_OFST 24
+/* Length of AOE transfer (total) */
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_LENGTH_OFST 28
+/* Length of host transfer (total) */
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_LENGTH_OFST 32
+/* Offset back from aoe_address to apply operation to */
#define MC_CMD_FC_IN_TIMED_READ_SET_OFFSET_OFST 36
+/* Data to apply at offset */
#define MC_CMD_FC_IN_TIMED_READ_SET_DATA_OFST 40
#define MC_CMD_FC_IN_TIMED_READ_SET_FLAGS_OFST 44
#define MC_CMD_FC_IN_TIMED_READ_SET_INDIRECT_LBN 0
@@ -1091,18 +1754,21 @@
#define MC_CMD_FC_IN_TIMED_READ_SET_READ 0x1 /* enum */
#define MC_CMD_FC_IN_TIMED_READ_SET_WRITE 0x2 /* enum */
#define MC_CMD_FC_IN_TIMED_READ_SET_READWRITE 0x3 /* enum */
+/* Period at which reads are performed (100ms units) */
#define MC_CMD_FC_IN_TIMED_READ_SET_PERIOD_OFST 48
/* MC_CMD_FC_IN_TIMED_READ_GET msgrequest */
#define MC_CMD_FC_IN_TIMED_READ_GET_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_TIMED_READ_OP_OFST 4 */
+/* FC supplied handle */
#define MC_CMD_FC_IN_TIMED_READ_GET_FC_HANDLE_OFST 8
/* MC_CMD_FC_IN_TIMED_READ_CLEAR msgrequest */
#define MC_CMD_FC_IN_TIMED_READ_CLEAR_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_TIMED_READ_OP_OFST 4 */
+/* FC supplied handle */
#define MC_CMD_FC_IN_TIMED_READ_CLEAR_FC_HANDLE_OFST 8
/* MC_CMD_FC_IN_LOG msgrequest */
@@ -1116,14 +1782,18 @@
#define MC_CMD_FC_IN_LOG_ADDR_RANGE_LEN 20
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_LOG_OP_OFST 4 */
+/* Partition offset into flash */
#define MC_CMD_FC_IN_LOG_ADDR_RANGE_OFFSET_OFST 8
+/* Partition length */
#define MC_CMD_FC_IN_LOG_ADDR_RANGE_LENGTH_OFST 12
+/* Partition erase size */
#define MC_CMD_FC_IN_LOG_ADDR_RANGE_ERASE_SIZE_OFST 16
/* MC_CMD_FC_IN_LOG_JTAG_UART msgrequest */
#define MC_CMD_FC_IN_LOG_JTAG_UART_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_LOG_OP_OFST 4 */
+/* Enable/disable printing to JTAG UART */
#define MC_CMD_FC_IN_LOG_JTAG_UART_ENABLE_OFST 8
/* MC_CMD_FC_IN_CLOCK msgrequest */
@@ -1132,6 +1802,7 @@
#define MC_CMD_FC_IN_CLOCK_OP_OFST 4
#define MC_CMD_FC_IN_CLOCK_GET_TIME 0x0 /* enum */
#define MC_CMD_FC_IN_CLOCK_SET_TIME 0x1 /* enum */
+/* Perform a clock operation */
#define MC_CMD_FC_IN_CLOCK_ID_OFST 8
#define MC_CMD_FC_IN_CLOCK_STATS 0x0 /* enum */
#define MC_CMD_FC_IN_CLOCK_MAC 0x1 /* enum */
@@ -1140,6 +1811,7 @@
#define MC_CMD_FC_IN_CLOCK_GET_TIME_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_CLOCK_OP_OFST 4 */
+/* Retrieve the clock value of the specified clock */
/* MC_CMD_FC_IN_CLOCK_ID_OFST 8 */
/* MC_CMD_FC_IN_CLOCK_SET_TIME msgrequest */
@@ -1151,6 +1823,7 @@
#define MC_CMD_FC_IN_CLOCK_SET_TIME_SECONDS_LEN 8
#define MC_CMD_FC_IN_CLOCK_SET_TIME_SECONDS_LO_OFST 12
#define MC_CMD_FC_IN_CLOCK_SET_TIME_SECONDS_HI_OFST 16
+/* Set the clock value of the specified clock */
#define MC_CMD_FC_IN_CLOCK_SET_TIME_NANOSECONDS_OFST 20
/* MC_CMD_FC_IN_DDR msgrequest */
@@ -1170,40 +1843,59 @@
#define MC_CMD_FC_IN_DDR_SET_SPD_LEN 148
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_DDR_OP_OFST 4 */
+/* Affected bank */
/* MC_CMD_FC_IN_DDR_BANK_OFST 8 */
+/* Flags */
#define MC_CMD_FC_IN_DDR_FLAGS_OFST 12
#define MC_CMD_FC_IN_DDR_SET_SPD_ACTIVE 0x1 /* enum */
+/* 128-byte page of serial presence detect data read from module's EEPROM */
#define MC_CMD_FC_IN_DDR_SPD_OFST 16
#define MC_CMD_FC_IN_DDR_SPD_LEN 1
#define MC_CMD_FC_IN_DDR_SPD_NUM 128
+/* Page index of the spd data copied into MC_CMD_FC_IN_DDR_SPD */
#define MC_CMD_FC_IN_DDR_SPD_PAGE_ID_OFST 144
/* MC_CMD_FC_IN_DDR_GET_STATUS msgrequest */
#define MC_CMD_FC_IN_DDR_GET_STATUS_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_DDR_OP_OFST 4 */
+/* Affected bank */
/* MC_CMD_FC_IN_DDR_BANK_OFST 8 */
/* MC_CMD_FC_IN_TIMESTAMP msgrequest */
#define MC_CMD_FC_IN_TIMESTAMP_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* FC timestamp operation code */
#define MC_CMD_FC_IN_TIMESTAMP_OP_OFST 4
-#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT 0x0 /* enum */
-#define MC_CMD_FC_IN_TIMESTAMP_READ_SNAPSHOT 0x1 /* enum */
-#define MC_CMD_FC_IN_TIMESTAMP_CLEAR_TRANSMIT 0x2 /* enum */
+/* enum: Read transmit timestamp(s) */
+#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT 0x0
+/* enum: Read snapshot timestamps */
+#define MC_CMD_FC_IN_TIMESTAMP_READ_SNAPSHOT 0x1
+/* enum: Clear all transmit timestamps */
+#define MC_CMD_FC_IN_TIMESTAMP_CLEAR_TRANSMIT 0x2
/* MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT msgrequest */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_LEN 28
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_OP_OFST 4
+/* Control filtering of the returned timestamp and sequence number specified
+ * here
+ */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_FILTER_OFST 8
-#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_LATEST 0x0 /* enum */
-#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_MATCH 0x1 /* enum */
+/* enum: Return most recent timestamp. No filtering */
+#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_LATEST 0x0
+/* enum: Match timestamp against the PTP clock ID, port number and sequence
+ * number specified
+ */
+#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_MATCH 0x1
+/* Clock identity of PTP packet for which timestamp required */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_CLOCK_ID_OFST 12
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_CLOCK_ID_LEN 8
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_CLOCK_ID_LO_OFST 12
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_CLOCK_ID_HI_OFST 16
+/* Port number of PTP packet for which timestamp required */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_PORT_NUM_OFST 20
+/* Sequence number of PTP packet for which timestamp required */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_SEQ_NUM_OFST 24
/* MC_CMD_FC_IN_TIMESTAMP_READ_SNAPSHOT msgrequest */
@@ -1219,10 +1911,14 @@
/* MC_CMD_FC_IN_SPI msgrequest */
#define MC_CMD_FC_IN_SPI_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* Basic commands for SPI Flash. */
#define MC_CMD_FC_IN_SPI_OP_OFST 4
-#define MC_CMD_FC_IN_SPI_READ 0x0 /* enum */
-#define MC_CMD_FC_IN_SPI_WRITE 0x1 /* enum */
-#define MC_CMD_FC_IN_SPI_ERASE 0x2 /* enum */
+/* enum: SPI Flash read */
+#define MC_CMD_FC_IN_SPI_READ 0x0
+/* enum: SPI Flash write */
+#define MC_CMD_FC_IN_SPI_WRITE 0x1
+/* enum: SPI Flash erase */
+#define MC_CMD_FC_IN_SPI_ERASE 0x2
/* MC_CMD_FC_IN_SPI_READ msgrequest */
#define MC_CMD_FC_IN_SPI_READ_LEN 16
@@ -1253,18 +1949,29 @@
/* MC_CMD_FC_IN_DIAG msgrequest */
#define MC_CMD_FC_IN_DIAG_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* Operation code indicating component type */
#define MC_CMD_FC_IN_DIAG_OP_OFST 4
-#define MC_CMD_FC_IN_DIAG_POWER_NOISE 0x0 /* enum */
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK 0x1 /* enum */
-#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL 0x2 /* enum */
+/* enum: Power noise generator. */
+#define MC_CMD_FC_IN_DIAG_POWER_NOISE 0x0
+/* enum: DDR soak test component. */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK 0x1
+/* enum: Diagnostics datapath control component. */
+#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL 0x2
/* MC_CMD_FC_IN_DIAG_POWER_NOISE msgrequest */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_OP_OFST 4
+/* Sub-opcode describing the operation to be carried out */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_SUB_OP_OFST 8
-#define MC_CMD_FC_IN_DIAG_POWER_NOISE_READ_CONFIG 0x0 /* enum */
-#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG 0x1 /* enum */
+/* enum: Read the configuration (the 32-bit values in each of the clock enable
+ * count and toggle count registers)
+ */
+#define MC_CMD_FC_IN_DIAG_POWER_NOISE_READ_CONFIG 0x0
+/* enum: Write a new configuration to the clock enable count and toggle count
+ * registers
+ */
+#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG 0x1
/* MC_CMD_FC_IN_DIAG_POWER_NOISE_READ_CONFIG msgrequest */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_READ_CONFIG_LEN 12
@@ -1277,28 +1984,42 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG_SUB_OP_OFST 8
+/* The 32-bit value to be written to the toggle count register */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG_TOGGLE_COUNT_OFST 12
+/* The 32-bit value to be written to the clock enable count register */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG_CLKEN_COUNT_OFST 16
/* MC_CMD_FC_IN_DIAG_DDR_SOAK msgrequest */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_OP_OFST 4
+/* Sub-opcode describing the operation to be carried out */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_SUB_OP_OFST 8
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START 0x0 /* enum */
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT 0x1 /* enum */
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP 0x2 /* enum */
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR 0x3 /* enum */
+/* enum: Starts DDR soak test on selected banks */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START 0x0
+/* enum: Read status of DDR soak test */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT 0x1
+/* enum: Stop test */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP 0x2
+/* enum: Set or clear bit that triggers fake errors. These cause subsequent
+ * tests to fail until the bit is cleared.
+ */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR 0x3
/* MC_CMD_FC_IN_DIAG_DDR_SOAK_START msgrequest */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_LEN 24
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_SUB_OP_OFST 8
+/* Mask of DDR banks to be tested */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_BANK_MASK_OFST 12
+/* Pattern to use in the soak test */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_TEST_PATTERN_OFST 16
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_ZEROS 0x0 /* enum */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_ONES 0x1 /* enum */
+/* Either multiple automatic tests until a STOP command is issued, or one
+ * single test
+ */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_TEST_TYPE_OFST 20
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_ONGOING_TEST 0x0 /* enum */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_SINGLE_TEST 0x1 /* enum */
@@ -1308,6 +2029,7 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT_SUB_OP_OFST 8
+/* DDR bank to read status from */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT_BANK_ID_OFST 12
#define MC_CMD_FC_DDR_BANK0 0x0 /* enum */
#define MC_CMD_FC_DDR_BANK1 0x1 /* enum */
@@ -1320,6 +2042,7 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP_SUB_OP_OFST 8
+/* Mask of DDR banks to be tested */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP_BANK_MASK_OFST 12
/* MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR msgrequest */
@@ -1327,6 +2050,7 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_SUB_OP_OFST 8
+/* Mask of DDR banks to set/clear error flag on */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_BANK_MASK_OFST 12
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_FLAG_ACTION_OFST 16
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_CLEAR 0x0 /* enum */
@@ -1336,15 +2060,19 @@
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_OP_OFST 4
+/* Sub-opcode describing the operation to be carried out */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SUB_OP_OFST 8
-#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE 0x0 /* enum */
-#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG 0x1 /* enum */
+/* enum: Set a known datapath configuration */
+#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE 0x0
+/* enum: Apply raw config to datapath control registers */
+#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG 0x1
/* MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE msgrequest */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_LEN 16
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_SUB_OP_OFST 8
+/* Datapath configuration identifier */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_MODE_OFST 12
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_PASSTHROUGH 0x0 /* enum */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_SNAKE 0x1 /* enum */
@@ -1354,8 +2082,11 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_SUB_OP_OFST 8
+/* Value to write into control register 1 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_CONTROL1_OFST 12
+/* Value to write into control register 2 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_CONTROL2_OFST 16
+/* Value to write into control register 3 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_CONTROL3_OFST 20
/* MC_CMD_FC_OUT msgresponse */
@@ -1444,7 +2175,8 @@
#define MC_CMD_FC_MAC_RX_STATS_JABBERS 0x16 /* enum */
#define MC_CMD_FC_MAC_RX_STATS_FRAGMENTS 0x17 /* enum */
#define MC_CMD_FC_MAC_RX_MAC_CONTROL_FRAMES 0x18 /* enum */
-#define MC_CMD_FC_MAC_RX_NSTATS 0x19 /* enum */
+/* enum: (Last entry) */
+#define MC_CMD_FC_MAC_RX_NSTATS 0x19
/* MC_CMD_FC_OUT_MAC_GET_TX_STATS msgresponse */
#define MC_CMD_FC_OUT_MAC_GET_TX_STATS_LEN ((((0-1+(64*MC_CMD_FC_MAC_TX_NSTATS))+1))>>3)
@@ -1475,10 +2207,12 @@
#define MC_CMD_FC_MAC_TX_STATS_PKTS_1024_1518 0x13 /* enum */
#define MC_CMD_FC_MAC_TX_STATS_PKTS_1519_TX_MTU 0x14 /* enum */
#define MC_CMD_FC_MAC_TX_MAC_CONTROL_FRAMES 0x15 /* enum */
-#define MC_CMD_FC_MAC_TX_NSTATS 0x16 /* enum */
+/* enum: (Last entry) */
+#define MC_CMD_FC_MAC_TX_NSTATS 0x16
/* MC_CMD_FC_OUT_MAC_GET_STATS msgresponse */
#define MC_CMD_FC_OUT_MAC_GET_STATS_LEN ((((0-1+(64*MC_CMD_FC_MAC_NSTATS_PER_BLOCK))+1))>>3)
+/* MAC Statistics */
#define MC_CMD_FC_OUT_MAC_GET_STATS_STATISTICS_OFST 0
#define MC_CMD_FC_OUT_MAC_GET_STATS_STATISTICS_LEN 8
#define MC_CMD_FC_OUT_MAC_GET_STATS_STATISTICS_LO_OFST 0
@@ -1499,10 +2233,14 @@
#define MC_CMD_FC_OUT_DDR_TEST_POLL_STATUS_OFST 0
#define MC_CMD_FC_OUT_DDR_TEST_POLL_CODE_LBN 0
#define MC_CMD_FC_OUT_DDR_TEST_POLL_CODE_WIDTH 8
-#define MC_CMD_FC_OP_DDR_TEST_NONE 0x0 /* enum */
-#define MC_CMD_FC_OP_DDR_TEST_INPROGRESS 0x1 /* enum */
-#define MC_CMD_FC_OP_DDR_TEST_SUCCESS 0x2 /* enum */
-#define MC_CMD_FC_OP_DDR_TEST_TIMER_EXPIRED 0x3 /* enum */
+/* enum: Test not yet initiated */
+#define MC_CMD_FC_OP_DDR_TEST_NONE 0x0
+/* enum: Test is in progress */
+#define MC_CMD_FC_OP_DDR_TEST_INPROGRESS 0x1
+/* enum: Timed completed */
+#define MC_CMD_FC_OP_DDR_TEST_SUCCESS 0x2
+/* enum: Test did not complete in specified time */
+#define MC_CMD_FC_OP_DDR_TEST_TIMER_EXPIRED 0x3
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_T0_LBN 11
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_T0_WIDTH 1
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_T1_LBN 10
@@ -1511,6 +2249,7 @@
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_B0_WIDTH 1
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_B1_LBN 8
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_B1_WIDTH 1
+/* Test result from FPGA */
#define MC_CMD_FC_OUT_DDR_TEST_POLL_RESULT_OFST 4
#define MC_CMD_FC_OUT_DDR_TEST_POLL_FPGA_SUPPORTS_T0_LBN 31
#define MC_CMD_FC_OUT_DDR_TEST_POLL_FPGA_SUPPORTS_T0_WIDTH 1
@@ -1539,23 +2278,35 @@
/* MC_CMD_FC_OUT_GET_ASSERT msgresponse */
#define MC_CMD_FC_OUT_GET_ASSERT_LEN 144
+/* Assertion status flag. */
#define MC_CMD_FC_OUT_GET_ASSERT_GLOBAL_FLAGS_OFST 0
#define MC_CMD_FC_OUT_GET_ASSERT_STATE_LBN 8
#define MC_CMD_FC_OUT_GET_ASSERT_STATE_WIDTH 8
-#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_CLEAR 0x0 /* enum */
-#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_NEW 0x1 /* enum */
-#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_NOTIFIED 0x2 /* enum */
+/* enum: No crash data available */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_CLEAR 0x0
+/* enum: New crash data available */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_NEW 0x1
+/* enum: Crash data has been sent */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_NOTIFIED 0x2
#define MC_CMD_FC_OUT_GET_ASSERT_TYPE_LBN 0
#define MC_CMD_FC_OUT_GET_ASSERT_TYPE_WIDTH 8
-#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_NONE 0x0 /* enum */
-#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_EXCEPTION 0x1 /* enum */
-#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_ASSERTION 0x2 /* enum */
+/* enum: No crash has been recorded. */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_NONE 0x0
+/* enum: Crash due to exception. */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_EXCEPTION 0x1
+/* enum: Crash due to assertion. */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_ASSERTION 0x2
+/* Failing PC value */
#define MC_CMD_FC_OUT_GET_ASSERT_SAVED_PC_OFFS_OFST 4
+/* Saved GP regs */
#define MC_CMD_FC_OUT_GET_ASSERT_GP_REGS_OFFS_OFST 8
#define MC_CMD_FC_OUT_GET_ASSERT_GP_REGS_OFFS_LEN 4
#define MC_CMD_FC_OUT_GET_ASSERT_GP_REGS_OFFS_NUM 31
+/* Exception Type */
#define MC_CMD_FC_OUT_GET_ASSERT_EXCEPTION_TYPE_OFFS_OFST 132
+/* Instruction at which exception occurred */
#define MC_CMD_FC_OUT_GET_ASSERT_EXCEPTION_PC_ADDR_OFFS_OFST 136
+/* BAD Address that triggered address-based exception */
#define MC_CMD_FC_OUT_GET_ASSERT_EXCEPTION_BAD_ADDR_OFFS_OFST 140
/* MC_CMD_FC_OUT_FPGA_BUILD msgresponse */
@@ -1573,6 +2324,7 @@
#define MC_CMD_FC_OUT_FPGA_BUILD_VERSION_MINOR_WIDTH 8
#define MC_CMD_FC_OUT_FPGA_BUILD_BUILD_NUM_LBN 0
#define MC_CMD_FC_OUT_FPGA_BUILD_BUILD_NUM_WIDTH 4
+/* Build timestamp (seconds since epoch) */
#define MC_CMD_FC_OUT_FPGA_BUILD_TIMESTAMP_OFST 4
#define MC_CMD_FC_OUT_FPGA_BUILD_PARAMETERS_OFST 8
#define MC_CMD_FC_OUT_FPGA_BUILD_FPGA_TYPE_LBN 0
@@ -1650,6 +2402,7 @@
#define MC_CMD_FC_OUT_FPGA_SERVICES_VERSION_MINOR_WIDTH 8
#define MC_CMD_FC_OUT_FPGA_SERVICES_BUILD_NUM_LBN 0
#define MC_CMD_FC_OUT_FPGA_SERVICES_BUILD_NUM_WIDTH 4
+/* Build timestamp (seconds since epoch) */
#define MC_CMD_FC_OUT_FPGA_SERVICES_TIMESTAMP_OFST 4
#define MC_CMD_FC_OUT_FPGA_SERVICES_PARAMETERS_OFST 8
#define MC_CMD_FC_OUT_FPGA_SERVICES_FC_FLASH_BOOTED_LBN 8
@@ -1686,6 +2439,7 @@
/* MC_CMD_FC_OUT_BSP_VERSION msgresponse */
#define MC_CMD_FC_OUT_BSP_VERSION_LEN 4
+/* Qsys system ID */
#define MC_CMD_FC_OUT_BSP_VERSION_SYSID_OFST 0
#define MC_CMD_FC_OUT_BSP_VERSION_VERSION_MAJOR_LBN 12
#define MC_CMD_FC_OUT_BSP_VERSION_VERSION_MAJOR_WIDTH 4
@@ -1696,11 +2450,14 @@
/* MC_CMD_FC_OUT_READ_MAP_COUNT msgresponse */
#define MC_CMD_FC_OUT_READ_MAP_COUNT_LEN 4
+/* Number of maps */
#define MC_CMD_FC_OUT_READ_MAP_COUNT_NUM_MAPS_OFST 0
/* MC_CMD_FC_OUT_READ_MAP_INDEX msgresponse */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN 164
+/* Index of the map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_INDEX_OFST 0
+/* Options for the map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_OPTIONS_OFST 4
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ALIGN_8 0x0 /* enum */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ALIGN_16 0x1 /* enum */
@@ -1713,19 +2470,24 @@
#define MC_CMD_FC_OUT_READ_MAP_INDEX_PERM_WRITE 0x20 /* enum */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_FREE 0x0 /* enum */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_LICENSED 0x40 /* enum */
+/* Address of start of map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ADDRESS_OFST 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ADDRESS_LEN 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ADDRESS_LO_OFST 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ADDRESS_HI_OFST 12
+/* Length of address map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN_OFST 16
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN_LEN 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN_LO_OFST 16
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN_HI_OFST 20
+/* Component information field */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_COMP_INFO_OFST 24
+/* License expiry data for map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_DATE_OFST 28
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_DATE_LEN 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_DATE_LO_OFST 28
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_DATE_HI_OFST 32
+/* Name of the component */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_NAME_OFST 36
#define MC_CMD_FC_OUT_READ_MAP_INDEX_NAME_LEN 1
#define MC_CMD_FC_OUT_READ_MAP_INDEX_NAME_NUM 128
@@ -1735,7 +2497,9 @@
/* MC_CMD_FC_OUT_CAPABILITIES msgresponse */
#define MC_CMD_FC_OUT_CAPABILITIES_LEN 8
+/* Number of internal ports */
#define MC_CMD_FC_OUT_CAPABILITIES_INTERNAL_OFST 0
+/* Number of external ports */
#define MC_CMD_FC_OUT_CAPABILITIES_EXTERNAL_OFST 4
/* MC_CMD_FC_OUT_GLOBAL_FLAGS msgresponse */
@@ -1769,34 +2533,46 @@
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_VOD_WIDTH 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_1STPOSTTAP_LBN 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_1STPOSTTAP_WIDTH 16
+/* Transceiver Transmit settings */
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_SETTINGS_1_OFST 4
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_PRETAP_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_PRETAP_WIDTH 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_2NDPOSTTAP_LBN 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_2NDPOSTTAP_WIDTH 16
+/* Transceiver Receive settings */
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_SETTINGS_OFST 8
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_DC_GAIN_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_DC_GAIN_WIDTH 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_EQ_CONTROL_LBN 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_EQ_CONTROL_WIDTH 16
+/* Rx eye opening */
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_OFST 12
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_WIDTH_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_WIDTH_WIDTH 16
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_HEIGHT_LBN 16
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_HEIGHT_WIDTH 16
+/* PCS status word */
#define MC_CMD_FC_OUT_UHLINK_PHY_PCS_STATUS_OFST 16
+/* Link status word */
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_STATE_WORD_OFST 20
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_STATE_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_STATE_WIDTH 1
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_CONFIGURED_LBN 1
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_CONFIGURED_WIDTH 1
+/* Current SFp parameters applied */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_PARAMS_OFST 24
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_PARAMS_LEN 20
+/* Link speed is 100, 1000, 10000 */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_SPEED_OFST 24
+/* Length of copper cable - zero when not relevant */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_COPPER_LEN_OFST 28
+/* True if a dual speed SFP+ module */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_DUAL_SPEED_OFST 32
+/* True if an SFP Module is present (other fields valid when true) */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_PRESENT_OFST 36
+/* The type of the SFP+ Module */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_TYPE_OFST 40
+/* PHY config flags */
#define MC_CMD_FC_OUT_UHLINK_PHY_PHY_CFG_OFST 44
#define MC_CMD_FC_OUT_UHLINK_PHY_PHY_CFG_DFE_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_PHY_CFG_DFE_WIDTH 1
@@ -1807,9 +2583,13 @@
/* MC_CMD_FC_OUT_UHLINK_MAC msgresponse */
#define MC_CMD_FC_OUT_UHLINK_MAC_LEN 20
+/* MAC configuration applied */
#define MC_CMD_FC_OUT_UHLINK_MAC_CONFIG_OFST 0
+/* MTU size */
#define MC_CMD_FC_OUT_UHLINK_MAC_MTU_OFST 4
+/* IF Mode status */
#define MC_CMD_FC_OUT_UHLINK_MAC_IF_STATUS_OFST 8
+/* MAC address configured */
#define MC_CMD_FC_OUT_UHLINK_MAC_ADDR_OFST 12
#define MC_CMD_FC_OUT_UHLINK_MAC_ADDR_LEN 8
#define MC_CMD_FC_OUT_UHLINK_MAC_ADDR_LO_OFST 12
@@ -1817,6 +2597,7 @@
/* MC_CMD_FC_OUT_UHLINK_RX_EYE msgresponse */
#define MC_CMD_FC_OUT_UHLINK_RX_EYE_LEN ((((0-1+(32*MC_CMD_FC_UHLINK_RX_EYE_PER_BLOCK))+1))>>3)
+/* Rx Eye measurements */
#define MC_CMD_FC_OUT_UHLINK_RX_EYE_RX_EYE_OFST 0
#define MC_CMD_FC_OUT_UHLINK_RX_EYE_RX_EYE_LEN 4
#define MC_CMD_FC_OUT_UHLINK_RX_EYE_RX_EYE_NUM MC_CMD_FC_UHLINK_RX_EYE_PER_BLOCK
@@ -1826,7 +2607,9 @@
/* MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT msgresponse */
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_LEN ((((32-1+(64*MC_CMD_FC_UHLINK_RX_EYE_PLOT_ROWS_PER_BLOCK))+1))>>3)
+/* Has the eye plot dump completed and data returned is valid? */
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_VALID_OFST 0
+/* Rx Eye binary plot */
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_ROWS_OFST 4
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_ROWS_LEN 8
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_ROWS_LO_OFST 4
@@ -1851,12 +2634,16 @@
/* MC_CMD_FC_OUT_LICENSE msgresponse */
#define MC_CMD_FC_OUT_LICENSE_LEN 12
+/* Count of valid keys */
#define MC_CMD_FC_OUT_LICENSE_VALID_KEYS_OFST 0
+/* Count of invalid keys */
#define MC_CMD_FC_OUT_LICENSE_INVALID_KEYS_OFST 4
+/* Count of blacklisted keys */
#define MC_CMD_FC_OUT_LICENSE_BLACKLISTED_KEYS_OFST 8
/* MC_CMD_FC_OUT_STARTUP msgresponse */
#define MC_CMD_FC_OUT_STARTUP_LEN 4
+/* Capabilities of the FPGA/FC */
#define MC_CMD_FC_OUT_STARTUP_CAPABILITIES_OFST 0
#define MC_CMD_FC_OUT_STARTUP_CAN_ACCESS_FLASH_LBN 0
#define MC_CMD_FC_OUT_STARTUP_CAN_ACCESS_FLASH_WIDTH 1
@@ -1865,6 +2652,7 @@
#define MC_CMD_FC_OUT_DMA_READ_LENMIN 1
#define MC_CMD_FC_OUT_DMA_READ_LENMAX 252
#define MC_CMD_FC_OUT_DMA_READ_LEN(num) (0+1*(num))
+/* The data read */
#define MC_CMD_FC_OUT_DMA_READ_DATA_OFST 0
#define MC_CMD_FC_OUT_DMA_READ_DATA_LEN 1
#define MC_CMD_FC_OUT_DMA_READ_DATA_MINNUM 1
@@ -1872,27 +2660,36 @@
/* MC_CMD_FC_OUT_TIMED_READ_SET msgresponse */
#define MC_CMD_FC_OUT_TIMED_READ_SET_LEN 4
+/* Timer handle */
#define MC_CMD_FC_OUT_TIMED_READ_SET_FC_HANDLE_OFST 0
/* MC_CMD_FC_OUT_TIMED_READ_GET msgresponse */
#define MC_CMD_FC_OUT_TIMED_READ_GET_LEN 52
+/* Host supplied handle (unique) */
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_HANDLE_OFST 0
+/* Address into which to transfer data in host */
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_DMA_ADDRESS_OFST 4
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_DMA_ADDRESS_LEN 8
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_DMA_ADDRESS_LO_OFST 4
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_DMA_ADDRESS_HI_OFST 8
+/* AOE address from which to transfer data */
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_ADDRESS_OFST 12
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_ADDRESS_LEN 8
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_ADDRESS_LO_OFST 12
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_ADDRESS_HI_OFST 16
+/* Length of AOE transfer (total) */
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_LENGTH_OFST 20
+/* Length of host transfer (total) */
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_LENGTH_OFST 24
+/* See FLAGS entry for MC_CMD_FC_IN_TIMED_READ_SET */
#define MC_CMD_FC_OUT_TIMED_READ_GET_FLAGS_OFST 28
#define MC_CMD_FC_OUT_TIMED_READ_GET_PERIOD_OFST 32
+/* When active, start read time */
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_START_OFST 36
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_START_LEN 8
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_START_LO_OFST 36
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_START_HI_OFST 40
+/* When active, end read time */
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_END_OFST 44
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_END_LEN 8
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_END_LO_OFST 44
@@ -1964,7 +2761,9 @@
/* MC_CMD_FC_OUT_DIAG_POWER_NOISE_READ_CONFIG msgresponse */
#define MC_CMD_FC_OUT_DIAG_POWER_NOISE_READ_CONFIG_LEN 8
+/* The 32-bit value read from the toggle count register */
#define MC_CMD_FC_OUT_DIAG_POWER_NOISE_READ_CONFIG_TOGGLE_COUNT_OFST 0
+/* The 32-bit value read from the clock enable count register */
#define MC_CMD_FC_OUT_DIAG_POWER_NOISE_READ_CONFIG_CLKEN_COUNT_OFST 4
/* MC_CMD_FC_OUT_DIAG_POWER_NOISE_WRITE_CONFIG msgresponse */
@@ -1975,6 +2774,7 @@
/* MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT msgresponse */
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_LEN 8
+/* DDR soak test status word; bits [4:0] are relevant. */
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_STATUS_OFST 0
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_PASSED_LBN 0
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_PASSED_WIDTH 1
@@ -1986,6 +2786,7 @@
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_TIMEOUT_WIDTH 1
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_PNF_LBN 4
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_PNF_WIDTH 1
+/* DDR soak test error count */
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_ERR_COUNT_OFST 4
/* MC_CMD_FC_OUT_DIAG_DDR_SOAK_STOP msgresponse */
@@ -2002,39 +2803,70 @@
/***********************************/
-/* MC_CMD_AOE
- * AOE operations (on MC rather than FC)
+/* MC_CMD_AOE
+ * AOE operations on MC
*/
-#define MC_CMD_AOE 0xa
+#define MC_CMD_AOE 0xa
/* MC_CMD_AOE_IN msgrequest */
#define MC_CMD_AOE_IN_LEN 4
#define MC_CMD_AOE_IN_OP_HDR_OFST 0
#define MC_CMD_AOE_IN_OP_LBN 0
#define MC_CMD_AOE_IN_OP_WIDTH 8
-#define MC_CMD_AOE_OP_INFO 0x1 /* enum */
-#define MC_CMD_AOE_OP_CURRENTS 0x2 /* enum */
-#define MC_CMD_AOE_OP_TEMPERATURES 0x3 /* enum */
-#define MC_CMD_AOE_OP_CPLD_IDLE 0x4 /* enum */
-#define MC_CMD_AOE_OP_CPLD_READ 0x5 /* enum */
-#define MC_CMD_AOE_OP_CPLD_WRITE 0x6 /* enum */
-#define MC_CMD_AOE_OP_CPLD_INSTRUCTION 0x7 /* enum */
-#define MC_CMD_AOE_OP_CPLD_REPROGRAM 0x8 /* enum */
-#define MC_CMD_AOE_OP_POWER 0x9 /* enum */
-#define MC_CMD_AOE_OP_LOAD 0xa /* enum */
-#define MC_CMD_AOE_OP_FAN_CONTROL 0xb /* enum */
-#define MC_CMD_AOE_OP_FAN_FAILURES 0xc /* enum */
-#define MC_CMD_AOE_OP_MAC_STATS 0xd /* enum */
-#define MC_CMD_AOE_OP_GET_PHY_MEDIA_INFO 0xe /* enum */
-#define MC_CMD_AOE_OP_JTAG_WRITE 0xf /* enum */
-#define MC_CMD_AOE_OP_FPGA_ACCESS 0x10 /* enum */
-#define MC_CMD_AOE_OP_SET_MTU_OFFSET 0x11 /* enum */
-#define MC_CMD_AOE_OP_LINK_STATE 0x12 /* enum */
-#define MC_CMD_AOE_OP_SIENA_STATS 0x13 /* enum */
-#define MC_CMD_AOE_OP_DDR 0x14 /* enum */
-#define MC_CMD_AOE_OP_FC 0x15 /* enum */
-#define MC_CMD_AOE_OP_DDR_ECC_STATUS 0x16 /* enum */
-#define MC_CMD_AOE_OP_MC_SPI_MASTER 0x17 /* enum */
+/* enum: FPGA and CPLD information */
+#define MC_CMD_AOE_OP_INFO 0x1
+/* enum: Currents and voltages read from MCP3424s; DEBUG */
+#define MC_CMD_AOE_OP_CURRENTS 0x2
+/* enum: Temperatures at locations around the PCB; DEBUG */
+#define MC_CMD_AOE_OP_TEMPERATURES 0x3
+/* enum: Set CPLD to idle */
+#define MC_CMD_AOE_OP_CPLD_IDLE 0x4
+/* enum: Read from CPLD register */
+#define MC_CMD_AOE_OP_CPLD_READ 0x5
+/* enum: Write to CPLD register */
+#define MC_CMD_AOE_OP_CPLD_WRITE 0x6
+/* enum: Execute CPLD instruction */
+#define MC_CMD_AOE_OP_CPLD_INSTRUCTION 0x7
+/* enum: Reprogram the CPLD on the AOE device */
+#define MC_CMD_AOE_OP_CPLD_REPROGRAM 0x8
+/* enum: AOE power control */
+#define MC_CMD_AOE_OP_POWER 0x9
+/* enum: AOE image loading */
+#define MC_CMD_AOE_OP_LOAD 0xa
+/* enum: Fan monitoring */
+#define MC_CMD_AOE_OP_FAN_CONTROL 0xb
+/* enum: Fan failures since last reset */
+#define MC_CMD_AOE_OP_FAN_FAILURES 0xc
+/* enum: Get generic AOE MAC statistics */
+#define MC_CMD_AOE_OP_MAC_STATS 0xd
+/* enum: Retrieve PHY specific information */
+#define MC_CMD_AOE_OP_GET_PHY_MEDIA_INFO 0xe
+/* enum: Write a number of JTAG primitive commands, return will give data */
+#define MC_CMD_AOE_OP_JTAG_WRITE 0xf
+/* enum: Control access to the FPGA via the Siena JTAG Chain */
+#define MC_CMD_AOE_OP_FPGA_ACCESS 0x10
+/* enum: Set the MTU offset between Siena and AOE MACs */
+#define MC_CMD_AOE_OP_SET_MTU_OFFSET 0x11
+/* enum: How link state is handled */
+#define MC_CMD_AOE_OP_LINK_STATE 0x12
+/* enum: How Siena MAC statistics are reported (deprecated - use
+ * MC_CMD_AOE_OP_ASIC_STATS)
+ */
+#define MC_CMD_AOE_OP_SIENA_STATS 0x13
+/* enum: How native ASIC MAC statistics are reported - replaces the deprecated
+ * command MC_CMD_AOE_OP_SIENA_STATS
+ */
+#define MC_CMD_AOE_OP_ASIC_STATS 0x13
+/* enum: DDR memory information */
+#define MC_CMD_AOE_OP_DDR 0x14
+/* enum: FC control */
+#define MC_CMD_AOE_OP_FC 0x15
+/* enum: DDR ECC status reads */
+#define MC_CMD_AOE_OP_DDR_ECC_STATUS 0x16
+/* enum: Commands for MC-SPI Master emulation */
+#define MC_CMD_AOE_OP_MC_SPI_MASTER 0x17
+/* enum: Commands for FC boot control */
+#define MC_CMD_AOE_OP_FC_BOOT 0x18
/* MC_CMD_AOE_OUT msgresponse */
#define MC_CMD_AOE_OUT_LEN 0
@@ -2077,31 +2909,46 @@
#define MC_CMD_AOE_IN_CPLD_REPROGRAM_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
#define MC_CMD_AOE_IN_CPLD_REPROGRAM_OP_OFST 4
-#define MC_CMD_AOE_IN_CPLD_REPROGRAM_REPROGRAM 0x1 /* enum */
-#define MC_CMD_AOE_IN_CPLD_REPROGRAM_REPROGRAM_EVENT 0x3 /* enum */
-#define MC_CMD_AOE_IN_CPLD_REPROGRAM_STATUS 0x4 /* enum */
+/* enum: Reprogram CPLD, poll for completion */
+#define MC_CMD_AOE_IN_CPLD_REPROGRAM_REPROGRAM 0x1
+/* enum: Reprogram CPLD, send event on completion */
+#define MC_CMD_AOE_IN_CPLD_REPROGRAM_REPROGRAM_EVENT 0x3
+/* enum: Get status of reprogramming operation */
+#define MC_CMD_AOE_IN_CPLD_REPROGRAM_STATUS 0x4
/* MC_CMD_AOE_IN_POWER msgrequest */
#define MC_CMD_AOE_IN_POWER_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* Turn on or off AOE power */
#define MC_CMD_AOE_IN_POWER_OP_OFST 4
-#define MC_CMD_AOE_IN_POWER_OFF 0x0 /* enum */
-#define MC_CMD_AOE_IN_POWER_ON 0x1 /* enum */
-#define MC_CMD_AOE_IN_POWER_CLEAR 0x2 /* enum */
-#define MC_CMD_AOE_IN_POWER_SHOW_CURRENT 0x3 /* enum */
-#define MC_CMD_AOE_IN_POWER_SHOW_PEAK 0x4 /* enum */
-#define MC_CMD_AOE_IN_POWER_DDR_LAST 0x5 /* enum */
-#define MC_CMD_AOE_IN_POWER_DDR_PEAK 0x6 /* enum */
-#define MC_CMD_AOE_IN_POWER_DDR_CLEAR 0x7 /* enum */
+/* enum: Turn off FPGA power */
+#define MC_CMD_AOE_IN_POWER_OFF 0x0
+/* enum: Turn on FPGA power */
+#define MC_CMD_AOE_IN_POWER_ON 0x1
+/* enum: Clear peak power measurement */
+#define MC_CMD_AOE_IN_POWER_CLEAR 0x2
+/* enum: Show current power in sensors output */
+#define MC_CMD_AOE_IN_POWER_SHOW_CURRENT 0x3
+/* enum: Show peak power in sensors output */
+#define MC_CMD_AOE_IN_POWER_SHOW_PEAK 0x4
+/* enum: Show current DDR current */
+#define MC_CMD_AOE_IN_POWER_DDR_LAST 0x5
+/* enum: Show peak DDR current */
+#define MC_CMD_AOE_IN_POWER_DDR_PEAK 0x6
+/* enum: Clear peak DDR current */
+#define MC_CMD_AOE_IN_POWER_DDR_CLEAR 0x7
/* MC_CMD_AOE_IN_LOAD msgrequest */
#define MC_CMD_AOE_IN_LOAD_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* Image to be loaded (0 - main or 1 - diagnostic) to load in normal sequence
+ */
#define MC_CMD_AOE_IN_LOAD_IMAGE_OFST 4
/* MC_CMD_AOE_IN_FAN_CONTROL msgrequest */
#define MC_CMD_AOE_IN_FAN_CONTROL_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* If non zero report measured fan RPM rather than nominal */
#define MC_CMD_AOE_IN_FAN_CONTROL_REAL_RPM_OFST 4
/* MC_CMD_AOE_IN_FAN_FAILURES msgrequest */
@@ -2111,7 +2958,9 @@
/* MC_CMD_AOE_IN_MAC_STATS msgrequest */
#define MC_CMD_AOE_IN_MAC_STATS_LEN 24
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* AOE port */
#define MC_CMD_AOE_IN_MAC_STATS_PORT_OFST 4
+/* Host memory address for statistics */
#define MC_CMD_AOE_IN_MAC_STATS_DMA_ADDR_OFST 8
#define MC_CMD_AOE_IN_MAC_STATS_DMA_ADDR_LEN 8
#define MC_CMD_AOE_IN_MAC_STATS_DMA_ADDR_LO_OFST 8
@@ -2131,11 +2980,13 @@
#define MC_CMD_AOE_IN_MAC_STATS_PERIODIC_NOEVENT_WIDTH 1
#define MC_CMD_AOE_IN_MAC_STATS_PERIOD_MS_LBN 16
#define MC_CMD_AOE_IN_MAC_STATS_PERIOD_MS_WIDTH 16
+/* Length of DMA data (optional) */
#define MC_CMD_AOE_IN_MAC_STATS_DMA_LEN_OFST 20
/* MC_CMD_AOE_IN_GET_PHY_MEDIA_INFO msgrequest */
#define MC_CMD_AOE_IN_GET_PHY_MEDIA_INFO_LEN 12
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* AOE port */
#define MC_CMD_AOE_IN_GET_PHY_MEDIA_INFO_PORT_OFST 4
#define MC_CMD_AOE_IN_GET_PHY_MEDIA_INFO_PAGE_OFST 8
@@ -2153,16 +3004,23 @@
/* MC_CMD_AOE_IN_FPGA_ACCESS msgrequest */
#define MC_CMD_AOE_IN_FPGA_ACCESS_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* Enable or disable access */
#define MC_CMD_AOE_IN_FPGA_ACCESS_OP_OFST 4
-#define MC_CMD_AOE_IN_FPGA_ACCESS_ENABLE 0x1 /* enum */
-#define MC_CMD_AOE_IN_FPGA_ACCESS_DISABLE 0x2 /* enum */
+/* enum: Enable access */
+#define MC_CMD_AOE_IN_FPGA_ACCESS_ENABLE 0x1
+/* enum: Disable access */
+#define MC_CMD_AOE_IN_FPGA_ACCESS_DISABLE 0x2
/* MC_CMD_AOE_IN_SET_MTU_OFFSET msgrequest */
#define MC_CMD_AOE_IN_SET_MTU_OFFSET_LEN 12
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* AOE port - when not ALL_EXTERNAL or ALL_INTERNAL specifies port number */
#define MC_CMD_AOE_IN_SET_MTU_OFFSET_PORT_OFST 4
-#define MC_CMD_AOE_IN_SET_MTU_OFFSET_ALL_EXTERNAL 0x8000 /* enum */
-#define MC_CMD_AOE_IN_SET_MTU_OFFSET_ALL_INTERNAL 0x4000 /* enum */
+/* enum: Apply to all external ports */
+#define MC_CMD_AOE_IN_SET_MTU_OFFSET_ALL_EXTERNAL 0x8000
+/* enum: Apply to all internal ports */
+#define MC_CMD_AOE_IN_SET_MTU_OFFSET_ALL_INTERNAL 0x4000
+/* The MTU offset to be applied to the external ports */
#define MC_CMD_AOE_IN_SET_MTU_OFFSET_OFFSET_OFST 8
/* MC_CMD_AOE_IN_LINK_STATE msgrequest */
@@ -2171,31 +3029,52 @@
#define MC_CMD_AOE_IN_LINK_STATE_MODE_OFST 4
#define MC_CMD_AOE_IN_LINK_STATE_CONFIG_MODE_LBN 0
#define MC_CMD_AOE_IN_LINK_STATE_CONFIG_MODE_WIDTH 8
-#define MC_CMD_AOE_IN_LINK_STATE_SIMPLE_SEPARATE 0x0 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_SIMPLE_COMBINED 0x1 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_DIAGNOSTIC 0x2 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_CUSTOM 0x3 /* enum */
+/* enum: AOE and associated external port */
+#define MC_CMD_AOE_IN_LINK_STATE_SIMPLE_SEPARATE 0x0
+/* enum: AOE and OR of all external ports */
+#define MC_CMD_AOE_IN_LINK_STATE_SIMPLE_COMBINED 0x1
+/* enum: Individual ports */
+#define MC_CMD_AOE_IN_LINK_STATE_DIAGNOSTIC 0x2
+/* enum: Configure link state mode on given AOE port */
+#define MC_CMD_AOE_IN_LINK_STATE_CUSTOM 0x3
#define MC_CMD_AOE_IN_LINK_STATE_OPERATION_LBN 8
#define MC_CMD_AOE_IN_LINK_STATE_OPERATION_WIDTH 8
-#define MC_CMD_AOE_IN_LINK_STATE_OP_NONE 0x0 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_OP_OR 0x1 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_OP_AND 0x2 /* enum */
+/* enum: No-op */
+#define MC_CMD_AOE_IN_LINK_STATE_OP_NONE 0x0
+/* enum: logical OR of all SFP ports link status */
+#define MC_CMD_AOE_IN_LINK_STATE_OP_OR 0x1
+/* enum: logical AND of all SFP ports link status */
+#define MC_CMD_AOE_IN_LINK_STATE_OP_AND 0x2
#define MC_CMD_AOE_IN_LINK_STATE_SFP_MASK_LBN 16
#define MC_CMD_AOE_IN_LINK_STATE_SFP_MASK_WIDTH 16
/* MC_CMD_AOE_IN_SIENA_STATS msgrequest */
#define MC_CMD_AOE_IN_SIENA_STATS_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* How MAC statistics are reported */
#define MC_CMD_AOE_IN_SIENA_STATS_MODE_OFST 4
-#define MC_CMD_AOE_IN_SIENA_STATS_STATS_SIENA 0x0 /* enum */
-#define MC_CMD_AOE_IN_SIENA_STATS_STATS_AOE 0x1 /* enum */
+/* enum: Statistics from Siena (default) */
+#define MC_CMD_AOE_IN_SIENA_STATS_STATS_SIENA 0x0
+/* enum: Statistics from AOE external ports */
+#define MC_CMD_AOE_IN_SIENA_STATS_STATS_AOE 0x1
+
+/* MC_CMD_AOE_IN_ASIC_STATS msgrequest */
+#define MC_CMD_AOE_IN_ASIC_STATS_LEN 8
+/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* How MAC statistics are reported */
+#define MC_CMD_AOE_IN_ASIC_STATS_MODE_OFST 4
+/* enum: Statistics from the ASIC (default) */
+#define MC_CMD_AOE_IN_ASIC_STATS_STATS_ASIC 0x0
+/* enum: Statistics from AOE external ports */
+#define MC_CMD_AOE_IN_ASIC_STATS_STATS_AOE 0x1
/* MC_CMD_AOE_IN_DDR msgrequest */
#define MC_CMD_AOE_IN_DDR_LEN 12
/* MC_CMD_AOE_IN_CMD_OFST 0 */
#define MC_CMD_AOE_IN_DDR_BANK_OFST 4
/* Enum values, see field(s): */
-/* MC_CMD_FC_IN_DDR_BANK */
+/* MC_CMD_FC/MC_CMD_FC_IN_DDR/MC_CMD_FC_IN_DDR_BANK */
+/* Page index of SPD data */
#define MC_CMD_AOE_IN_DDR_SPD_PAGE_ID_OFST 8
/* MC_CMD_AOE_IN_FC msgrequest */
@@ -2207,14 +3086,17 @@
/* MC_CMD_AOE_IN_CMD_OFST 0 */
#define MC_CMD_AOE_IN_DDR_ECC_STATUS_BANK_OFST 4
/* Enum values, see field(s): */
-/* MC_CMD_FC_IN_DDR_BANK */
+/* MC_CMD_FC/MC_CMD_FC_IN_DDR/MC_CMD_FC_IN_DDR_BANK */
/* MC_CMD_AOE_IN_MC_SPI_MASTER msgrequest */
#define MC_CMD_AOE_IN_MC_SPI_MASTER_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* Basic commands for MC SPI Master emulation. */
#define MC_CMD_AOE_IN_MC_SPI_MASTER_OP_OFST 4
-#define MC_CMD_AOE_IN_MC_SPI_MASTER_READ 0x0 /* enum */
-#define MC_CMD_AOE_IN_MC_SPI_MASTER_WRITE 0x1 /* enum */
+/* enum: MC SPI read */
+#define MC_CMD_AOE_IN_MC_SPI_MASTER_READ 0x0
+/* enum: MC SPI write */
+#define MC_CMD_AOE_IN_MC_SPI_MASTER_WRITE 0x1
/* MC_CMD_AOE_IN_MC_SPI_MASTER_READ msgrequest */
#define MC_CMD_AOE_IN_MC_SPI_MASTER_READ_LEN 12
@@ -2229,42 +3111,80 @@
#define MC_CMD_AOE_IN_MC_SPI_MASTER_WRITE_OFFSET_OFST 8
#define MC_CMD_AOE_IN_MC_SPI_MASTER_WRITE_DATA_OFST 12
+/* MC_CMD_AOE_IN_FC_BOOT msgrequest */
+#define MC_CMD_AOE_IN_FC_BOOT_LEN 8
+/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* FC boot control flags */
+#define MC_CMD_AOE_IN_FC_BOOT_CONTROL_OFST 4
+#define MC_CMD_AOE_IN_FC_BOOT_CONTROL_BOOT_ENABLE_LBN 0
+#define MC_CMD_AOE_IN_FC_BOOT_CONTROL_BOOT_ENABLE_WIDTH 1
+
/* MC_CMD_AOE_OUT_INFO msgresponse */
#define MC_CMD_AOE_OUT_INFO_LEN 44
+/* JTAG IDCODE of CPLD */
#define MC_CMD_AOE_OUT_INFO_CPLD_IDCODE_OFST 0
+/* Version of CPLD */
#define MC_CMD_AOE_OUT_INFO_CPLD_VERSION_OFST 4
+/* JTAG IDCODE of FPGA */
#define MC_CMD_AOE_OUT_INFO_FPGA_IDCODE_OFST 8
+/* JTAG USERCODE of FPGA */
#define MC_CMD_AOE_OUT_INFO_FPGA_VERSION_OFST 12
+/* FPGA type - read from CPLD straps */
#define MC_CMD_AOE_OUT_INFO_FPGA_TYPE_OFST 16
+/* FPGA state (debug) */
#define MC_CMD_AOE_OUT_INFO_FPGA_STATE_OFST 20
+/* FPGA image - partition from which loaded */
#define MC_CMD_AOE_OUT_INFO_FPGA_IMAGE_OFST 24
+/* FC state */
#define MC_CMD_AOE_OUT_INFO_FC_STATE_OFST 28
-#define MC_CMD_AOE_OUT_INFO_WATCHDOG 0x1 /* enum */
-#define MC_CMD_AOE_OUT_INFO_COMMS 0x2 /* enum */
+/* enum: Set if watchdog working */
+#define MC_CMD_AOE_OUT_INFO_WATCHDOG 0x1
+/* enum: Set if MC-FC communications working */
+#define MC_CMD_AOE_OUT_INFO_COMMS 0x2
+/* Random pieces of information */
#define MC_CMD_AOE_OUT_INFO_FLAGS_OFST 32
-#define MC_CMD_AOE_OUT_INFO_PEG_POWER 0x1 /* enum */
-#define MC_CMD_AOE_OUT_INFO_CPLD_GOOD 0x2 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FPGA_GOOD 0x4 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FPGA_POWER 0x8 /* enum */
-#define MC_CMD_AOE_OUT_INFO_BAD_SODIMM 0x10 /* enum */
-#define MC_CMD_AOE_OUT_INFO_HAS_BYTEBLASTER 0x20 /* enum */
+/* enum: Power to FPGA supplied by PEG connector, not PCIe bus */
+#define MC_CMD_AOE_OUT_INFO_PEG_POWER 0x1
+/* enum: CPLD apparently good */
+#define MC_CMD_AOE_OUT_INFO_CPLD_GOOD 0x2
+/* enum: FPGA working normally */
+#define MC_CMD_AOE_OUT_INFO_FPGA_GOOD 0x4
+/* enum: FPGA is powered */
+#define MC_CMD_AOE_OUT_INFO_FPGA_POWER 0x8
+/* enum: Board has incompatible SODIMMs fitted */
+#define MC_CMD_AOE_OUT_INFO_BAD_SODIMM 0x10
+/* enum: Board has ByteBlaster connected */
+#define MC_CMD_AOE_OUT_INFO_HAS_BYTEBLASTER 0x20
+/* Revision of Modena board */
#define MC_CMD_AOE_OUT_INFO_BOARD_REVISION_OFST 36
#define MC_CMD_AOE_OUT_INFO_UNKNOWN 0x0 /* enum */
#define MC_CMD_AOE_OUT_INFO_R1_0 0x10 /* enum */
#define MC_CMD_AOE_OUT_INFO_R1_1 0x11 /* enum */
#define MC_CMD_AOE_OUT_INFO_R1_2 0x12 /* enum */
+/* Result of FC booting - not valid while a ByteBlaster is connected. */
#define MC_CMD_AOE_OUT_INFO_FC_BOOT_RESULT_OFST 40
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_NO_ERROR 0x0 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_ADDRESS 0x1 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_MAGIC 0x2 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_TEXT 0x3 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_CHECKSUM 0x4 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_BSP 0x5 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_APP_EXECUTE 0x80 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_NO_BOOTROM 0xff /* enum */
+/* enum: No error */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_NO_ERROR 0x0
+/* enum: Bad address set in CPLD */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_ADDRESS 0x1
+/* enum: Bad header */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_MAGIC 0x2
+/* enum: Bad text section details */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_TEXT 0x3
+/* enum: Bad checksum */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_CHECKSUM 0x4
+/* enum: Bad BSP */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_BSP 0x5
+/* enum: FC application loaded and execution attempted */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_APP_EXECUTE 0x80
+/* enum: FC application Started */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_APP_STARTED 0x81
+/* enum: No bootrom in FPGA */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_NO_BOOTROM 0xff
/* MC_CMD_AOE_OUT_CURRENTS msgresponse */
#define MC_CMD_AOE_OUT_CURRENTS_LEN 68
+/* Set of currents and voltages (mA or mV as appropriate) */
#define MC_CMD_AOE_OUT_CURRENTS_VALUES_OFST 0
#define MC_CMD_AOE_OUT_CURRENTS_VALUES_LEN 4
#define MC_CMD_AOE_OUT_CURRENTS_VALUES_NUM 17
@@ -2288,10 +3208,12 @@
/* MC_CMD_AOE_OUT_TEMPERATURES msgresponse */
#define MC_CMD_AOE_OUT_TEMPERATURES_LEN 40
+/* Set of temperatures */
#define MC_CMD_AOE_OUT_TEMPERATURES_VALUES_OFST 0
#define MC_CMD_AOE_OUT_TEMPERATURES_VALUES_LEN 4
#define MC_CMD_AOE_OUT_TEMPERATURES_VALUES_NUM 10
-#define MC_CMD_AOE_OUT_TEMPERATURES_MAIN_0 0x0 /* enum */
+/* enum: The first set of enum values are for Modena code. */
+#define MC_CMD_AOE_OUT_TEMPERATURES_MAIN_0 0x0
#define MC_CMD_AOE_OUT_TEMPERATURES_MAIN_1 0x1 /* enum */
#define MC_CMD_AOE_OUT_TEMPERATURES_IND_0 0x2 /* enum */
#define MC_CMD_AOE_OUT_TEMPERATURES_IND_1 0x3 /* enum */
@@ -2301,15 +3223,27 @@
#define MC_CMD_AOE_OUT_TEMPERATURES_PSU 0x7 /* enum */
#define MC_CMD_AOE_OUT_TEMPERATURES_FPGA 0x8 /* enum */
#define MC_CMD_AOE_OUT_TEMPERATURES_SIENA 0x9 /* enum */
+/* enum: The second set of enum values are for Sorrento code. */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_MAIN_0 0x0
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_MAIN_1 0x1 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_IND_0 0x2 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_IND_1 0x3 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_SODIMM_0 0x4 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_SODIMM_1 0x5 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_FPGA 0x6 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_PHY0 0x7 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_PHY1 0x8 /* enum */
/* MC_CMD_AOE_OUT_CPLD_READ msgresponse */
#define MC_CMD_AOE_OUT_CPLD_READ_LEN 4
+/* The value read from the CPLD */
#define MC_CMD_AOE_OUT_CPLD_READ_VALUE_OFST 0
/* MC_CMD_AOE_OUT_FAN_FAILURES msgresponse */
#define MC_CMD_AOE_OUT_FAN_FAILURES_LENMIN 4
#define MC_CMD_AOE_OUT_FAN_FAILURES_LENMAX 252
#define MC_CMD_AOE_OUT_FAN_FAILURES_LEN(num) (0+4*(num))
+/* Failure counts for each fan */
#define MC_CMD_AOE_OUT_FAN_FAILURES_COUNT_OFST 0
#define MC_CMD_AOE_OUT_FAN_FAILURES_COUNT_LEN 4
#define MC_CMD_AOE_OUT_FAN_FAILURES_COUNT_MINNUM 1
@@ -2317,12 +3251,24 @@
/* MC_CMD_AOE_OUT_CPLD_REPROGRAM msgresponse */
#define MC_CMD_AOE_OUT_CPLD_REPROGRAM_LEN 4
+/* Results of status command (only) */
#define MC_CMD_AOE_OUT_CPLD_REPROGRAM_STATUS_OFST 0
+/* MC_CMD_AOE_OUT_POWER_OFF msgresponse */
+#define MC_CMD_AOE_OUT_POWER_OFF_LEN 0
+
+/* MC_CMD_AOE_OUT_POWER_ON msgresponse */
+#define MC_CMD_AOE_OUT_POWER_ON_LEN 0
+
+/* MC_CMD_AOE_OUT_LOAD msgresponse */
+#define MC_CMD_AOE_OUT_LOAD_LEN 0
+
/* MC_CMD_AOE_OUT_MAC_STATS_DMA msgresponse */
#define MC_CMD_AOE_OUT_MAC_STATS_DMA_LEN 0
-/* MC_CMD_AOE_OUT_MAC_STATS_NO_DMA msgresponse */
+/* MC_CMD_AOE_OUT_MAC_STATS_NO_DMA msgresponse: See MC_CMD_MAC_STATS_OUT_NO_DMA
+ * for details
+ */
#define MC_CMD_AOE_OUT_MAC_STATS_NO_DMA_LEN (((MC_CMD_MAC_NSTATS*64))>>3)
#define MC_CMD_AOE_OUT_MAC_STATS_NO_DMA_STATISTICS_OFST 0
#define MC_CMD_AOE_OUT_MAC_STATS_NO_DMA_STATISTICS_LEN 8
@@ -2334,6 +3280,7 @@
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_LENMIN 5
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_LENMAX 252
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_LEN(num) (4+1*(num))
+/* in bytes */
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_DATALEN_OFST 0
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_DATA_OFST 4
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_DATA_LEN 1
@@ -2344,7 +3291,9 @@
#define MC_CMD_AOE_OUT_JTAG_WRITE_LENMIN 12
#define MC_CMD_AOE_OUT_JTAG_WRITE_LENMAX 252
#define MC_CMD_AOE_OUT_JTAG_WRITE_LEN(num) (8+4*(num))
+/* Used to align the in and out data blocks so the MC can re-use the cmd */
#define MC_CMD_AOE_OUT_JTAG_WRITE_DATALEN_OFST 0
+/* out bytes */
#define MC_CMD_AOE_OUT_JTAG_WRITE_PAD_OFST 4
#define MC_CMD_AOE_OUT_JTAG_WRITE_DATA_OFST 8
#define MC_CMD_AOE_OUT_JTAG_WRITE_DATA_LEN 4
@@ -2358,6 +3307,7 @@
#define MC_CMD_AOE_OUT_DDR_LENMIN 17
#define MC_CMD_AOE_OUT_DDR_LENMAX 252
#define MC_CMD_AOE_OUT_DDR_LEN(num) (16+1*(num))
+/* Information on the module. */
#define MC_CMD_AOE_OUT_DDR_FLAGS_OFST 0
#define MC_CMD_AOE_OUT_DDR_PRESENT_LBN 0
#define MC_CMD_AOE_OUT_DDR_PRESENT_WIDTH 1
@@ -2365,25 +3315,42 @@
#define MC_CMD_AOE_OUT_DDR_POWERED_WIDTH 1
#define MC_CMD_AOE_OUT_DDR_OPERATIONAL_LBN 2
#define MC_CMD_AOE_OUT_DDR_OPERATIONAL_WIDTH 1
+#define MC_CMD_AOE_OUT_DDR_NOT_REACHABLE_LBN 3
+#define MC_CMD_AOE_OUT_DDR_NOT_REACHABLE_WIDTH 1
+/* Memory size, in MB. */
#define MC_CMD_AOE_OUT_DDR_CAPACITY_OFST 4
+/* The memory type, as reported from SPD information */
#define MC_CMD_AOE_OUT_DDR_TYPE_OFST 8
+/* Nominal voltage of the module (as applied) */
#define MC_CMD_AOE_OUT_DDR_VOLTAGE_OFST 12
+/* SPD data read from the module */
#define MC_CMD_AOE_OUT_DDR_SPD_OFST 16
#define MC_CMD_AOE_OUT_DDR_SPD_LEN 1
#define MC_CMD_AOE_OUT_DDR_SPD_MINNUM 1
#define MC_CMD_AOE_OUT_DDR_SPD_MAXNUM 236
+/* MC_CMD_AOE_OUT_SET_MTU_OFFSET msgresponse */
+#define MC_CMD_AOE_OUT_SET_MTU_OFFSET_LEN 0
+
/* MC_CMD_AOE_OUT_LINK_STATE msgresponse */
#define MC_CMD_AOE_OUT_LINK_STATE_LEN 0
+/* MC_CMD_AOE_OUT_SIENA_STATS msgresponse */
+#define MC_CMD_AOE_OUT_SIENA_STATS_LEN 0
+
+/* MC_CMD_AOE_OUT_ASIC_STATS msgresponse */
+#define MC_CMD_AOE_OUT_ASIC_STATS_LEN 0
+
/* MC_CMD_AOE_OUT_FC msgresponse */
#define MC_CMD_AOE_OUT_FC_LEN 0
/* MC_CMD_AOE_OUT_DDR_ECC_STATUS msgresponse */
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_LEN 8
+/* Flags describing status info on the module. */
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_FLAGS_OFST 0
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_VALID_LBN 0
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_VALID_WIDTH 1
+/* DDR ECC status on the module. */
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_STATUS_OFST 4
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_SBE_LBN 0
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_SBE_WIDTH 1
@@ -2408,51 +3375,113 @@
/* MC_CMD_AOE_OUT_MC_SPI_MASTER msgresponse */
#define MC_CMD_AOE_OUT_MC_SPI_MASTER_LEN 0
+/* MC_CMD_AOE_OUT_FC_BOOT msgresponse */
+#define MC_CMD_AOE_OUT_FC_BOOT_LEN 0
+
/***********************************/
-/* MC_CMD_PTP
+/* MC_CMD_PTP
* Perform PTP operation
*/
-#define MC_CMD_PTP 0xb
+#define MC_CMD_PTP 0xb
+#undef MC_CMD_0xb_PRIVILEGE_CTG
+
+#define MC_CMD_0xb_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_PTP_IN msgrequest */
#define MC_CMD_PTP_IN_LEN 1
+/* PTP operation code */
#define MC_CMD_PTP_IN_OP_OFST 0
#define MC_CMD_PTP_IN_OP_LEN 1
-#define MC_CMD_PTP_OP_ENABLE 0x1 /* enum */
-#define MC_CMD_PTP_OP_DISABLE 0x2 /* enum */
-#define MC_CMD_PTP_OP_TRANSMIT 0x3 /* enum */
-#define MC_CMD_PTP_OP_READ_NIC_TIME 0x4 /* enum */
-#define MC_CMD_PTP_OP_STATUS 0x5 /* enum */
-#define MC_CMD_PTP_OP_ADJUST 0x6 /* enum */
-#define MC_CMD_PTP_OP_SYNCHRONIZE 0x7 /* enum */
-#define MC_CMD_PTP_OP_MANFTEST_BASIC 0x8 /* enum */
-#define MC_CMD_PTP_OP_MANFTEST_PACKET 0x9 /* enum */
-#define MC_CMD_PTP_OP_RESET_STATS 0xa /* enum */
-#define MC_CMD_PTP_OP_DEBUG 0xb /* enum */
-#define MC_CMD_PTP_OP_FPGAREAD 0xc /* enum */
-#define MC_CMD_PTP_OP_FPGAWRITE 0xd /* enum */
-#define MC_CMD_PTP_OP_CLOCK_OFFSET_ADJUST 0xe /* enum */
-#define MC_CMD_PTP_OP_CLOCK_FREQ_ADJUST 0xf /* enum */
-#define MC_CMD_PTP_OP_RX_SET_VLAN_FILTER 0x10 /* enum */
-#define MC_CMD_PTP_OP_RX_SET_UUID_FILTER 0x11 /* enum */
-#define MC_CMD_PTP_OP_RX_SET_DOMAIN_FILTER 0x12 /* enum */
-#define MC_CMD_PTP_OP_SET_CLK_SRC 0x13 /* enum */
-#define MC_CMD_PTP_OP_RST_CLK 0x14 /* enum */
-#define MC_CMD_PTP_OP_PPS_ENABLE 0x15 /* enum */
-#define MC_CMD_PTP_OP_MAX 0x16 /* enum */
+/* enum: Enable PTP packet timestamping operation. */
+#define MC_CMD_PTP_OP_ENABLE 0x1
+/* enum: Disable PTP packet timestamping operation. */
+#define MC_CMD_PTP_OP_DISABLE 0x2
+/* enum: Send a PTP packet. */
+#define MC_CMD_PTP_OP_TRANSMIT 0x3
+/* enum: Read the current NIC time. */
+#define MC_CMD_PTP_OP_READ_NIC_TIME 0x4
+/* enum: Get the current PTP status. */
+#define MC_CMD_PTP_OP_STATUS 0x5
+/* enum: Adjust the PTP NIC's time. */
+#define MC_CMD_PTP_OP_ADJUST 0x6
+/* enum: Synchronize host and NIC time. */
+#define MC_CMD_PTP_OP_SYNCHRONIZE 0x7
+/* enum: Basic manufacturing tests. */
+#define MC_CMD_PTP_OP_MANFTEST_BASIC 0x8
+/* enum: Packet based manufacturing tests. */
+#define MC_CMD_PTP_OP_MANFTEST_PACKET 0x9
+/* enum: Reset some of the PTP related statistics */
+#define MC_CMD_PTP_OP_RESET_STATS 0xa
+/* enum: Debug operations to MC. */
+#define MC_CMD_PTP_OP_DEBUG 0xb
+/* enum: Read an FPGA register */
+#define MC_CMD_PTP_OP_FPGAREAD 0xc
+/* enum: Write an FPGA register */
+#define MC_CMD_PTP_OP_FPGAWRITE 0xd
+/* enum: Apply an offset to the NIC clock */
+#define MC_CMD_PTP_OP_CLOCK_OFFSET_ADJUST 0xe
+/* enum: Change Apply an offset to the NIC clock */
+#define MC_CMD_PTP_OP_CLOCK_FREQ_ADJUST 0xf
+/* enum: Set the MC packet filter VLAN tags for received PTP packets */
+#define MC_CMD_PTP_OP_RX_SET_VLAN_FILTER 0x10
+/* enum: Set the MC packet filter UUID for received PTP packets */
+#define MC_CMD_PTP_OP_RX_SET_UUID_FILTER 0x11
+/* enum: Set the MC packet filter Domain for received PTP packets */
+#define MC_CMD_PTP_OP_RX_SET_DOMAIN_FILTER 0x12
+/* enum: Set the clock source */
+#define MC_CMD_PTP_OP_SET_CLK_SRC 0x13
+/* enum: Reset value of Timer Reg. */
+#define MC_CMD_PTP_OP_RST_CLK 0x14
+/* enum: Enable the forwarding of PPS events to the host */
+#define MC_CMD_PTP_OP_PPS_ENABLE 0x15
+/* enum: Get the time format used by this NIC for PTP operations */
+#define MC_CMD_PTP_OP_GET_TIME_FORMAT 0x16
+/* enum: Get the clock attributes. NOTE- extended version of
+ * MC_CMD_PTP_OP_GET_TIME_FORMAT
+ */
+#define MC_CMD_PTP_OP_GET_ATTRIBUTES 0x16
+/* enum: Get corrections that should be applied to the various different
+ * timestamps
+ */
+#define MC_CMD_PTP_OP_GET_TIMESTAMP_CORRECTIONS 0x17
+/* enum: Subscribe to receive periodic time events indicating the current NIC
+ * time
+ */
+#define MC_CMD_PTP_OP_TIME_EVENT_SUBSCRIBE 0x18
+/* enum: Unsubscribe to stop receiving time events */
+#define MC_CMD_PTP_OP_TIME_EVENT_UNSUBSCRIBE 0x19
+/* enum: PPS based manfacturing tests. Requires PPS output to be looped to PPS
+ * input on the same NIC.
+ */
+#define MC_CMD_PTP_OP_MANFTEST_PPS 0x1a
+/* enum: Set the PTP sync status. Status is used by firmware to report to event
+ * subscribers.
+ */
+#define MC_CMD_PTP_OP_SET_SYNC_STATUS 0x1b
+/* enum: Above this for future use. */
+#define MC_CMD_PTP_OP_MAX 0x1c
/* MC_CMD_PTP_IN_ENABLE msgrequest */
#define MC_CMD_PTP_IN_ENABLE_LEN 16
#define MC_CMD_PTP_IN_CMD_OFST 0
#define MC_CMD_PTP_IN_PERIPH_ID_OFST 4
+/* Event queue for PTP events */
#define MC_CMD_PTP_IN_ENABLE_QUEUE_OFST 8
+/* PTP timestamping mode */
#define MC_CMD_PTP_IN_ENABLE_MODE_OFST 12
-#define MC_CMD_PTP_MODE_V1 0x0 /* enum */
-#define MC_CMD_PTP_MODE_V1_VLAN 0x1 /* enum */
-#define MC_CMD_PTP_MODE_V2 0x2 /* enum */
-#define MC_CMD_PTP_MODE_V2_VLAN 0x3 /* enum */
-#define MC_CMD_PTP_MODE_V2_ENHANCED 0x4 /* enum */
+/* enum: PTP, version 1 */
+#define MC_CMD_PTP_MODE_V1 0x0
+/* enum: PTP, version 1, with VLAN headers - deprecated */
+#define MC_CMD_PTP_MODE_V1_VLAN 0x1
+/* enum: PTP, version 2 */
+#define MC_CMD_PTP_MODE_V2 0x2
+/* enum: PTP, version 2, with VLAN headers - deprecated */
+#define MC_CMD_PTP_MODE_V2_VLAN 0x3
+/* enum: PTP, version 2, with improved UUID filtering */
+#define MC_CMD_PTP_MODE_V2_ENHANCED 0x4
+/* enum: FCoE (seconds and microseconds) */
+#define MC_CMD_PTP_MODE_FCOE 0x5
/* MC_CMD_PTP_IN_DISABLE msgrequest */
#define MC_CMD_PTP_IN_DISABLE_LEN 8
@@ -2465,7 +3494,9 @@
#define MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num))
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Transmit packet length */
#define MC_CMD_PTP_IN_TRANSMIT_LENGTH_OFST 8
+/* Transmit packet data */
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST 12
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MINNUM 1
@@ -2485,19 +3516,31 @@
#define MC_CMD_PTP_IN_ADJUST_LEN 24
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Frequency adjustment 40 bit fixed point ns */
#define MC_CMD_PTP_IN_ADJUST_FREQ_OFST 8
#define MC_CMD_PTP_IN_ADJUST_FREQ_LEN 8
#define MC_CMD_PTP_IN_ADJUST_FREQ_LO_OFST 8
#define MC_CMD_PTP_IN_ADJUST_FREQ_HI_OFST 12
-#define MC_CMD_PTP_IN_ADJUST_BITS 0x28 /* enum */
+/* enum: Number of fractional bits in frequency adjustment */
+#define MC_CMD_PTP_IN_ADJUST_BITS 0x28
+/* Time adjustment in seconds */
#define MC_CMD_PTP_IN_ADJUST_SECONDS_OFST 16
+/* Time adjustment major value */
+#define MC_CMD_PTP_IN_ADJUST_MAJOR_OFST 16
+/* Time adjustment in nanoseconds */
#define MC_CMD_PTP_IN_ADJUST_NANOSECONDS_OFST 20
+/* Time adjustment minor value */
+#define MC_CMD_PTP_IN_ADJUST_MINOR_OFST 20
/* MC_CMD_PTP_IN_SYNCHRONIZE msgrequest */
#define MC_CMD_PTP_IN_SYNCHRONIZE_LEN 20
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Number of time readings to capture */
#define MC_CMD_PTP_IN_SYNCHRONIZE_NUMTIMESETS_OFST 8
+/* Host address in which to write "synchronization started" indication (64
+ * bits)
+ */
#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_OFST 12
#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LEN 8
#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LO_OFST 12
@@ -2512,17 +3555,20 @@
#define MC_CMD_PTP_IN_MANFTEST_PACKET_LEN 12
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Enable or disable packet testing */
#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_OFST 8
/* MC_CMD_PTP_IN_RESET_STATS msgrequest */
#define MC_CMD_PTP_IN_RESET_STATS_LEN 8
/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* Reset PTP statistics */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
/* MC_CMD_PTP_IN_DEBUG msgrequest */
#define MC_CMD_PTP_IN_DEBUG_LEN 12
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Debug operations */
#define MC_CMD_PTP_IN_DEBUG_DEBUG_PARAM_OFST 8
/* MC_CMD_PTP_IN_FPGAREAD msgrequest */
@@ -2548,24 +3594,34 @@
#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_LEN 16
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Time adjustment in seconds */
#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_SECONDS_OFST 8
+/* Time adjustment major value */
+#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MAJOR_OFST 8
+/* Time adjustment in nanoseconds */
#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_NANOSECONDS_OFST 12
+/* Time adjustment minor value */
+#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MINOR_OFST 12
/* MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST msgrequest */
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_LEN 16
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Frequency adjustment 40 bit fixed point ns */
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_OFST 8
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_LEN 8
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_LO_OFST 8
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_HI_OFST 12
+/* enum: Number of fractional bits in frequency adjustment */
/* MC_CMD_PTP_IN_ADJUST_BITS 0x28 */
/* MC_CMD_PTP_IN_RX_SET_VLAN_FILTER msgrequest */
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_LEN 24
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Number of VLAN tags, 0 if not VLAN */
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_NUM_VLAN_TAGS_OFST 8
+/* Set of VLAN tags to filter against */
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_VLAN_TAG_OFST 12
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_VLAN_TAG_LEN 4
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_VLAN_TAG_NUM 3
@@ -2574,7 +3630,9 @@
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_LEN 20
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* 1 to enable UUID filtering, 0 to disable */
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_ENABLE_OFST 8
+/* UUID to filter against */
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_UUID_OFST 12
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_UUID_LEN 8
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_UUID_LO_OFST 12
@@ -2584,82 +3642,237 @@
#define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_LEN 16
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* 1 to enable Domain filtering, 0 to disable */
#define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_ENABLE_OFST 8
+/* Domain number to filter against */
#define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_DOMAIN_OFST 12
+/* MC_CMD_PTP_IN_SET_CLK_SRC msgrequest */
+#define MC_CMD_PTP_IN_SET_CLK_SRC_LEN 12
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Set the clock source. */
+#define MC_CMD_PTP_IN_SET_CLK_SRC_CLK_OFST 8
+/* enum: Internal. */
+#define MC_CMD_PTP_CLK_SRC_INTERNAL 0x0
+/* enum: External. */
+#define MC_CMD_PTP_CLK_SRC_EXTERNAL 0x1
+
+/* MC_CMD_PTP_IN_RST_CLK msgrequest */
+#define MC_CMD_PTP_IN_RST_CLK_LEN 8
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* Reset value of Timer Reg. */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
/* MC_CMD_PTP_IN_PPS_ENABLE msgrequest */
#define MC_CMD_PTP_IN_PPS_ENABLE_LEN 12
/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* Enable or disable */
#define MC_CMD_PTP_IN_PPS_ENABLE_OP_OFST 4
-#define MC_CMD_PTP_ENABLE_PPS 0x0 /* enum */
-#define MC_CMD_PTP_DISABLE_PPS 0x1 /* enum */
+/* enum: Enable */
+#define MC_CMD_PTP_ENABLE_PPS 0x0
+/* enum: Disable */
+#define MC_CMD_PTP_DISABLE_PPS 0x1
+/* Queue id to send events back */
#define MC_CMD_PTP_IN_PPS_ENABLE_QUEUE_ID_OFST 8
+/* MC_CMD_PTP_IN_GET_TIME_FORMAT msgrequest */
+#define MC_CMD_PTP_IN_GET_TIME_FORMAT_LEN 8
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_GET_ATTRIBUTES msgrequest */
+#define MC_CMD_PTP_IN_GET_ATTRIBUTES_LEN 8
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS msgrequest */
+#define MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS_LEN 8
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE msgrequest */
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_LEN 12
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Original field containing queue ID. Now extended to include flags. */
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_OFST 8
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_LBN 0
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_WIDTH 16
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_REPORT_SYNC_STATUS_LBN 31
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_REPORT_SYNC_STATUS_WIDTH 1
+
+/* MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE msgrequest */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_LEN 16
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Unsubscribe options */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_CONTROL_OFST 8
+/* enum: Unsubscribe a single queue */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_SINGLE 0x0
+/* enum: Unsubscribe all queues */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_ALL 0x1
+/* Event queue ID */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_QUEUE_OFST 12
+
+/* MC_CMD_PTP_IN_MANFTEST_PPS msgrequest */
+#define MC_CMD_PTP_IN_MANFTEST_PPS_LEN 12
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* 1 to enable PPS test mode, 0 to disable and return result. */
+#define MC_CMD_PTP_IN_MANFTEST_PPS_TEST_ENABLE_OFST 8
+
+/* MC_CMD_PTP_IN_SET_SYNC_STATUS msgrequest */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_LEN 24
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* NIC - Host System Clock Synchronization status */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_STATUS_OFST 8
+/* enum: Host System clock and NIC clock are not in sync */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_NOT_IN_SYNC 0x0
+/* enum: Host System clock and NIC clock are synchronized */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_IN_SYNC 0x1
+/* If synchronized, number of seconds until clocks should be considered to be
+ * no longer in sync.
+ */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_TIMEOUT_OFST 12
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_RESERVED0_OFST 16
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_RESERVED1_OFST 20
+
/* MC_CMD_PTP_OUT msgresponse */
#define MC_CMD_PTP_OUT_LEN 0
/* MC_CMD_PTP_OUT_TRANSMIT msgresponse */
#define MC_CMD_PTP_OUT_TRANSMIT_LEN 8
+/* Value of seconds timestamp */
#define MC_CMD_PTP_OUT_TRANSMIT_SECONDS_OFST 0
+/* Timestamp major value */
+#define MC_CMD_PTP_OUT_TRANSMIT_MAJOR_OFST 0
+/* Value of nanoseconds timestamp */
#define MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_OFST 4
+/* Timestamp minor value */
+#define MC_CMD_PTP_OUT_TRANSMIT_MINOR_OFST 4
+
+/* MC_CMD_PTP_OUT_TIME_EVENT_SUBSCRIBE msgresponse */
+#define MC_CMD_PTP_OUT_TIME_EVENT_SUBSCRIBE_LEN 0
+
+/* MC_CMD_PTP_OUT_TIME_EVENT_UNSUBSCRIBE msgresponse */
+#define MC_CMD_PTP_OUT_TIME_EVENT_UNSUBSCRIBE_LEN 0
/* MC_CMD_PTP_OUT_READ_NIC_TIME msgresponse */
#define MC_CMD_PTP_OUT_READ_NIC_TIME_LEN 8
+/* Value of seconds timestamp */
#define MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_OFST 0
+/* Timestamp major value */
+#define MC_CMD_PTP_OUT_READ_NIC_TIME_MAJOR_OFST 0
+/* Value of nanoseconds timestamp */
#define MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_OFST 4
+/* Timestamp minor value */
+#define MC_CMD_PTP_OUT_READ_NIC_TIME_MINOR_OFST 4
/* MC_CMD_PTP_OUT_STATUS msgresponse */
#define MC_CMD_PTP_OUT_STATUS_LEN 64
+/* Frequency of NIC's hardware clock */
#define MC_CMD_PTP_OUT_STATUS_CLOCK_FREQ_OFST 0
+/* Number of packets transmitted and timestamped */
#define MC_CMD_PTP_OUT_STATUS_STATS_TX_OFST 4
+/* Number of packets received and timestamped */
#define MC_CMD_PTP_OUT_STATUS_STATS_RX_OFST 8
+/* Number of packets timestamped by the FPGA */
#define MC_CMD_PTP_OUT_STATUS_STATS_TS_OFST 12
+/* Number of packets filter matched */
#define MC_CMD_PTP_OUT_STATUS_STATS_FM_OFST 16
+/* Number of packets not filter matched */
#define MC_CMD_PTP_OUT_STATUS_STATS_NFM_OFST 20
+/* Number of PPS overflows (noise on input?) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_OFST 24
+/* Number of PPS bad periods */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_OFST 28
+/* Minimum period of PPS pulse in nanoseconds */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_OFST 32
+/* Maximum period of PPS pulse in nanoseconds */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_OFST 36
+/* Last period of PPS pulse in nanoseconds */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_OFST 40
+/* Mean period of PPS pulse in nanoseconds */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_OFST 44
+/* Minimum offset of PPS pulse in nanoseconds (signed) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_OFST 48
+/* Maximum offset of PPS pulse in nanoseconds (signed) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_OFST 52
+/* Last offset of PPS pulse in nanoseconds (signed) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_OFST 56
+/* Mean offset of PPS pulse in nanoseconds (signed) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_OFST 60
/* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMIN 20
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMAX 240
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LEN(num) (0+20*(num))
+/* A set of host and NIC times */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_OFST 0
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN 20
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MINNUM 1
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM 12
+/* Host time immediately before NIC's hardware clock read */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0
+/* Value of seconds timestamp */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_OFST 4
+/* Timestamp major value */
+#define MC_CMD_PTP_OUT_SYNCHRONIZE_MAJOR_OFST 4
+/* Value of nanoseconds timestamp */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_OFST 8
+/* Timestamp minor value */
+#define MC_CMD_PTP_OUT_SYNCHRONIZE_MINOR_OFST 8
+/* Host time immediately after NIC's hardware clock read */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_OFST 12
+/* Number of nanoseconds waited after reading NIC's hardware clock */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_WAITNS_OFST 16
/* MC_CMD_PTP_OUT_MANFTEST_BASIC msgresponse */
#define MC_CMD_PTP_OUT_MANFTEST_BASIC_LEN 8
+/* Results of testing */
#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_RESULT_OFST 0
-#define MC_CMD_PTP_MANF_SUCCESS 0x0 /* enum */
-#define MC_CMD_PTP_MANF_FPGA_LOAD 0x1 /* enum */
-#define MC_CMD_PTP_MANF_FPGA_VERSION 0x2 /* enum */
-#define MC_CMD_PTP_MANF_FPGA_REGISTERS 0x3 /* enum */
-#define MC_CMD_PTP_MANF_OSCILLATOR 0x4 /* enum */
-#define MC_CMD_PTP_MANF_TIMESTAMPS 0x5 /* enum */
-#define MC_CMD_PTP_MANF_PACKET_COUNT 0x6 /* enum */
-#define MC_CMD_PTP_MANF_FILTER_COUNT 0x7 /* enum */
-#define MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8 /* enum */
-#define MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9 /* enum */
+/* enum: Successful test */
+#define MC_CMD_PTP_MANF_SUCCESS 0x0
+/* enum: FPGA load failed */
+#define MC_CMD_PTP_MANF_FPGA_LOAD 0x1
+/* enum: FPGA version invalid */
+#define MC_CMD_PTP_MANF_FPGA_VERSION 0x2
+/* enum: FPGA registers incorrect */
+#define MC_CMD_PTP_MANF_FPGA_REGISTERS 0x3
+/* enum: Oscillator possibly not working? */
+#define MC_CMD_PTP_MANF_OSCILLATOR 0x4
+/* enum: Timestamps not increasing */
+#define MC_CMD_PTP_MANF_TIMESTAMPS 0x5
+/* enum: Mismatched packet count */
+#define MC_CMD_PTP_MANF_PACKET_COUNT 0x6
+/* enum: Mismatched packet count (Siena filter and FPGA) */
+#define MC_CMD_PTP_MANF_FILTER_COUNT 0x7
+/* enum: Not enough packets to perform timestamp check */
+#define MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8
+/* enum: Timestamp trigger GPIO not working */
+#define MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9
+/* enum: Insufficient PPS events to perform checks */
+#define MC_CMD_PTP_MANF_PPS_ENOUGH 0xa
+/* enum: PPS time event period not sufficiently close to 1s. */
+#define MC_CMD_PTP_MANF_PPS_PERIOD 0xb
+/* enum: PPS time event nS reading not sufficiently close to zero. */
+#define MC_CMD_PTP_MANF_PPS_NS 0xc
+/* enum: PTP peripheral registers incorrect */
+#define MC_CMD_PTP_MANF_REGISTERS 0xd
+/* enum: Failed to read time from PTP peripheral */
+#define MC_CMD_PTP_MANF_CLOCK_READ 0xe
+/* Presence of external oscillator */
#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_OFST 4
/* MC_CMD_PTP_OUT_MANFTEST_PACKET msgresponse */
#define MC_CMD_PTP_OUT_MANFTEST_PACKET_LEN 12
+/* Results of testing */
#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_RESULT_OFST 0
+/* Number of packets received by FPGA */
#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FPGACOUNT_OFST 4
+/* Number of packets received by Siena filters */
#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FILTERCOUNT_OFST 8
/* MC_CMD_PTP_OUT_FPGAREAD msgresponse */
@@ -2671,15 +3884,85 @@
#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MINNUM 1
#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MAXNUM 252
+/* MC_CMD_PTP_OUT_GET_TIME_FORMAT msgresponse */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_LEN 4
+/* Time format required/used by for this NIC. Applies to all PTP MCDI
+ * operations that pass times between the host and firmware. If this operation
+ * is not supported (older firmware) a format of seconds and nanoseconds should
+ * be assumed.
+ */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_FORMAT_OFST 0
+/* enum: Times are in seconds and nanoseconds */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_SECONDS_NANOSECONDS 0x0
+/* enum: Major register has units of 16 second per tick, minor 8 ns per tick */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_16SECONDS_8NANOSECONDS 0x1
+/* enum: Major register has units of seconds, minor 2^-27s per tick */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_SECONDS_27FRACTION 0x2
+
+/* MC_CMD_PTP_OUT_GET_ATTRIBUTES msgresponse */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_LEN 24
+/* Time format required/used by for this NIC. Applies to all PTP MCDI
+ * operations that pass times between the host and firmware. If this operation
+ * is not supported (older firmware) a format of seconds and nanoseconds should
+ * be assumed.
+ */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_TIME_FORMAT_OFST 0
+/* enum: Times are in seconds and nanoseconds */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_NANOSECONDS 0x0
+/* enum: Major register has units of 16 second per tick, minor 8 ns per tick */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_16SECONDS_8NANOSECONDS 0x1
+/* enum: Major register has units of seconds, minor 2^-27s per tick */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_27FRACTION 0x2
+/* Minimum acceptable value for a corrected synchronization timeset. When
+ * comparing host and NIC clock times, the MC returns a set of samples that
+ * contain the host start and end time, the MC time when the host start was
+ * detected and the time the MC waited between reading the time and detecting
+ * the host end. The corrected sync window is the difference between the host
+ * end and start times minus the time that the MC waited for host end.
+ */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SYNC_WINDOW_MIN_OFST 4
+/* Various PTP capabilities */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_CAPABILITIES_OFST 8
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_LBN 0
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_WIDTH 1
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED0_OFST 12
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED1_OFST 16
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED2_OFST 20
+
+/* MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS msgresponse */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_LEN 16
+/* Uncorrected error on transmit timestamps in NIC clock format */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_TRANSMIT_OFST 0
+/* Uncorrected error on receive timestamps in NIC clock format */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_RECEIVE_OFST 4
+/* Uncorrected error on PPS output in NIC clock format */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_OUT_OFST 8
+/* Uncorrected error on PPS input in NIC clock format */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_IN_OFST 12
+
+/* MC_CMD_PTP_OUT_MANFTEST_PPS msgresponse */
+#define MC_CMD_PTP_OUT_MANFTEST_PPS_LEN 4
+/* Results of testing */
+#define MC_CMD_PTP_OUT_MANFTEST_PPS_TEST_RESULT_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_PTP_OUT_MANFTEST_BASIC/TEST_RESULT */
+
+/* MC_CMD_PTP_OUT_SET_SYNC_STATUS msgresponse */
+#define MC_CMD_PTP_OUT_SET_SYNC_STATUS_LEN 0
+
/***********************************/
-/* MC_CMD_CSR_READ32
+/* MC_CMD_CSR_READ32
* Read 32bit words from the indirect memory map.
*/
-#define MC_CMD_CSR_READ32 0xc
+#define MC_CMD_CSR_READ32 0xc
+#undef MC_CMD_0xc_PRIVILEGE_CTG
+
+#define MC_CMD_0xc_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_CSR_READ32_IN msgrequest */
#define MC_CMD_CSR_READ32_IN_LEN 12
+/* Address */
#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0
#define MC_CMD_CSR_READ32_IN_STEP_OFST 4
#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8
@@ -2688,6 +3971,7 @@
#define MC_CMD_CSR_READ32_OUT_LENMIN 4
#define MC_CMD_CSR_READ32_OUT_LENMAX 252
#define MC_CMD_CSR_READ32_OUT_LEN(num) (0+4*(num))
+/* The last dword is the status, not a value read */
#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0
#define MC_CMD_CSR_READ32_OUT_BUFFER_LEN 4
#define MC_CMD_CSR_READ32_OUT_BUFFER_MINNUM 1
@@ -2695,15 +3979,19 @@
/***********************************/
-/* MC_CMD_CSR_WRITE32
+/* MC_CMD_CSR_WRITE32
* Write 32bit dwords to the indirect memory map.
*/
-#define MC_CMD_CSR_WRITE32 0xd
+#define MC_CMD_CSR_WRITE32 0xd
+#undef MC_CMD_0xd_PRIVILEGE_CTG
+
+#define MC_CMD_0xd_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_CSR_WRITE32_IN msgrequest */
#define MC_CMD_CSR_WRITE32_IN_LENMIN 12
#define MC_CMD_CSR_WRITE32_IN_LENMAX 252
#define MC_CMD_CSR_WRITE32_IN_LEN(num) (8+4*(num))
+/* Address */
#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0
#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4
#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8
@@ -2717,35 +4005,58 @@
/***********************************/
-/* MC_CMD_HP
- * HP specific commands.
+/* MC_CMD_HP
+ * These commands are used for HP related features. They are grouped under one
+ * MCDI command to avoid creating too many MCDI commands.
*/
-#define MC_CMD_HP 0x54
+#define MC_CMD_HP 0x54
+#undef MC_CMD_0x54_PRIVILEGE_CTG
+
+#define MC_CMD_0x54_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_HP_IN msgrequest */
#define MC_CMD_HP_IN_LEN 16
+/* HP OCSD sub-command. When address is not NULL, request activation of OCSD at
+ * the specified address with the specified interval.When address is NULL,
+ * INTERVAL is interpreted as a command: 0: stop OCSD / 1: Report OCSD current
+ * state / 2: (debug) Show temperature reported by one of the supported
+ * sensors.
+ */
#define MC_CMD_HP_IN_SUBCMD_OFST 0
-#define MC_CMD_HP_IN_OCSD_SUBCMD 0x0 /* enum */
-#define MC_CMD_HP_IN_LAST_SUBCMD 0x0 /* enum */
+/* enum: OCSD (Option Card Sensor Data) sub-command. */
+#define MC_CMD_HP_IN_OCSD_SUBCMD 0x0
+/* enum: Last known valid HP sub-command. */
+#define MC_CMD_HP_IN_LAST_SUBCMD 0x0
+/* The address to the array of sensor fields. (Or NULL to use a sub-command.)
+ */
#define MC_CMD_HP_IN_OCSD_ADDR_OFST 4
#define MC_CMD_HP_IN_OCSD_ADDR_LEN 8
#define MC_CMD_HP_IN_OCSD_ADDR_LO_OFST 4
#define MC_CMD_HP_IN_OCSD_ADDR_HI_OFST 8
+/* The requested update interval, in seconds. (Or the sub-command if ADDR is
+ * NULL.)
+ */
#define MC_CMD_HP_IN_OCSD_INTERVAL_OFST 12
/* MC_CMD_HP_OUT msgresponse */
#define MC_CMD_HP_OUT_LEN 4
#define MC_CMD_HP_OUT_OCSD_STATUS_OFST 0
-#define MC_CMD_HP_OUT_OCSD_STOPPED 0x1 /* enum */
-#define MC_CMD_HP_OUT_OCSD_STARTED 0x2 /* enum */
-#define MC_CMD_HP_OUT_OCSD_ALREADY_STARTED 0x3 /* enum */
+/* enum: OCSD stopped for this card. */
+#define MC_CMD_HP_OUT_OCSD_STOPPED 0x1
+/* enum: OCSD was successfully started with the address provided. */
+#define MC_CMD_HP_OUT_OCSD_STARTED 0x2
+/* enum: OCSD was already started for this card. */
+#define MC_CMD_HP_OUT_OCSD_ALREADY_STARTED 0x3
/***********************************/
-/* MC_CMD_STACKINFO
+/* MC_CMD_STACKINFO
* Get stack information.
*/
-#define MC_CMD_STACKINFO 0xf
+#define MC_CMD_STACKINFO 0xf
+#undef MC_CMD_0xf_PRIVILEGE_CTG
+
+#define MC_CMD_0xf_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_STACKINFO_IN msgrequest */
#define MC_CMD_STACKINFO_IN_LEN 0
@@ -2754,6 +4065,7 @@
#define MC_CMD_STACKINFO_OUT_LENMIN 12
#define MC_CMD_STACKINFO_OUT_LENMAX 252
#define MC_CMD_STACKINFO_OUT_LEN(num) (0+12*(num))
+/* (thread ptr, stack size, free space) for each thread in system */
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_OFST 0
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_LEN 12
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MINNUM 1
@@ -2761,61 +4073,105 @@
/***********************************/
-/* MC_CMD_MDIO_READ
+/* MC_CMD_MDIO_READ
* MDIO register read.
*/
-#define MC_CMD_MDIO_READ 0x10
+#define MC_CMD_MDIO_READ 0x10
+#undef MC_CMD_0x10_PRIVILEGE_CTG
+
+#define MC_CMD_0x10_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_MDIO_READ_IN msgrequest */
#define MC_CMD_MDIO_READ_IN_LEN 16
+/* Bus number; there are two MDIO buses: one for the internal PHY, and one for
+ * external devices.
+ */
#define MC_CMD_MDIO_READ_IN_BUS_OFST 0
-#define MC_CMD_MDIO_BUS_INTERNAL 0x0 /* enum */
-#define MC_CMD_MDIO_BUS_EXTERNAL 0x1 /* enum */
+/* enum: Internal. */
+#define MC_CMD_MDIO_BUS_INTERNAL 0x0
+/* enum: External. */
+#define MC_CMD_MDIO_BUS_EXTERNAL 0x1
+/* Port address */
#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4
+/* Device Address or clause 22. */
#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8
-#define MC_CMD_MDIO_CLAUSE22 0x20 /* enum */
+/* enum: By default all the MCDI MDIO operations perform clause45 mode. If you
+ * want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22.
+ */
+#define MC_CMD_MDIO_CLAUSE22 0x20
+/* Address */
#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12
/* MC_CMD_MDIO_READ_OUT msgresponse */
#define MC_CMD_MDIO_READ_OUT_LEN 8
+/* Value */
#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0
+/* Status the MDIO commands return the raw status bits from the MDIO block. A
+ * "good" transaction should have the DONE bit set and all other bits clear.
+ */
#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4
-#define MC_CMD_MDIO_STATUS_GOOD 0x8 /* enum */
+/* enum: Good. */
+#define MC_CMD_MDIO_STATUS_GOOD 0x8
/***********************************/
-/* MC_CMD_MDIO_WRITE
+/* MC_CMD_MDIO_WRITE
* MDIO register write.
*/
-#define MC_CMD_MDIO_WRITE 0x11
+#define MC_CMD_MDIO_WRITE 0x11
+#undef MC_CMD_0x11_PRIVILEGE_CTG
+
+#define MC_CMD_0x11_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_MDIO_WRITE_IN msgrequest */
#define MC_CMD_MDIO_WRITE_IN_LEN 20
+/* Bus number; there are two MDIO buses: one for the internal PHY, and one for
+ * external devices.
+ */
#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0
+/* enum: Internal. */
/* MC_CMD_MDIO_BUS_INTERNAL 0x0 */
+/* enum: External. */
/* MC_CMD_MDIO_BUS_EXTERNAL 0x1 */
+/* Port address */
#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4
+/* Device Address or clause 22. */
#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8
+/* enum: By default all the MCDI MDIO operations perform clause45 mode. If you
+ * want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22.
+ */
/* MC_CMD_MDIO_CLAUSE22 0x20 */
+/* Address */
#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12
+/* Value */
#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16
/* MC_CMD_MDIO_WRITE_OUT msgresponse */
#define MC_CMD_MDIO_WRITE_OUT_LEN 4
+/* Status; the MDIO commands return the raw status bits from the MDIO block. A
+ * "good" transaction should have the DONE bit set and all other bits clear.
+ */
#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0
+/* enum: Good. */
/* MC_CMD_MDIO_STATUS_GOOD 0x8 */
/***********************************/
-/* MC_CMD_DBI_WRITE
+/* MC_CMD_DBI_WRITE
* Write DBI register(s).
*/
-#define MC_CMD_DBI_WRITE 0x12
+#define MC_CMD_DBI_WRITE 0x12
+#undef MC_CMD_0x12_PRIVILEGE_CTG
+
+#define MC_CMD_0x12_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_DBI_WRITE_IN msgrequest */
#define MC_CMD_DBI_WRITE_IN_LENMIN 12
#define MC_CMD_DBI_WRITE_IN_LENMAX 252
#define MC_CMD_DBI_WRITE_IN_LEN(num) (0+12*(num))
+/* Each write op consists of an address (offset 0), byte enable/VF/CS2 (offset
+ * 32) and value (offset 64). See MC_CMD_DBIWROP_TYPEDEF.
+ */
#define MC_CMD_DBI_WRITE_IN_DBIWROP_OFST 0
#define MC_CMD_DBI_WRITE_IN_DBIWROP_LEN 12
#define MC_CMD_DBI_WRITE_IN_DBIWROP_MINNUM 1
@@ -2829,85 +4185,136 @@
#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST 0
#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_LBN 0
#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_WIDTH 32
-#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST 4
-#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_LBN 32
-#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_WIDTH 32
+#define MC_CMD_DBIWROP_TYPEDEF_PARMS_OFST 4
+#define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_LBN 16
+#define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_WIDTH 16
+#define MC_CMD_DBIWROP_TYPEDEF_VF_ACTIVE_LBN 15
+#define MC_CMD_DBIWROP_TYPEDEF_VF_ACTIVE_WIDTH 1
+#define MC_CMD_DBIWROP_TYPEDEF_CS2_LBN 14
+#define MC_CMD_DBIWROP_TYPEDEF_CS2_WIDTH 1
+#define MC_CMD_DBIWROP_TYPEDEF_PARMS_LBN 32
+#define MC_CMD_DBIWROP_TYPEDEF_PARMS_WIDTH 32
#define MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST 8
#define MC_CMD_DBIWROP_TYPEDEF_VALUE_LBN 64
#define MC_CMD_DBIWROP_TYPEDEF_VALUE_WIDTH 32
/***********************************/
-/* MC_CMD_PORT_READ32
- * Read a 32-bit register from the indirect port register map.
+/* MC_CMD_PORT_READ32
+ * Read a 32-bit register from the indirect port register map. The port to
+ * access is implied by the Shared memory channel used.
*/
-#define MC_CMD_PORT_READ32 0x14
+#define MC_CMD_PORT_READ32 0x14
/* MC_CMD_PORT_READ32_IN msgrequest */
#define MC_CMD_PORT_READ32_IN_LEN 4
+/* Address */
#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0
/* MC_CMD_PORT_READ32_OUT msgresponse */
#define MC_CMD_PORT_READ32_OUT_LEN 8
+/* Value */
#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0
+/* Status */
#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4
/***********************************/
-/* MC_CMD_PORT_WRITE32
- * Write a 32-bit register to the indirect port register map.
+/* MC_CMD_PORT_WRITE32
+ * Write a 32-bit register to the indirect port register map. The port to
+ * access is implied by the Shared memory channel used.
*/
-#define MC_CMD_PORT_WRITE32 0x15
+#define MC_CMD_PORT_WRITE32 0x15
/* MC_CMD_PORT_WRITE32_IN msgrequest */
#define MC_CMD_PORT_WRITE32_IN_LEN 8
+/* Address */
#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0
+/* Value */
#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4
/* MC_CMD_PORT_WRITE32_OUT msgresponse */
#define MC_CMD_PORT_WRITE32_OUT_LEN 4
+/* Status */
#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0
/***********************************/
-/* MC_CMD_PORT_READ128
- * Read a 128-bit register from the indirect port register map.
+/* MC_CMD_PORT_READ128
+ * Read a 128-bit register from the indirect port register map. The port to
+ * access is implied by the Shared memory channel used.
*/
-#define MC_CMD_PORT_READ128 0x16
+#define MC_CMD_PORT_READ128 0x16
/* MC_CMD_PORT_READ128_IN msgrequest */
#define MC_CMD_PORT_READ128_IN_LEN 4
+/* Address */
#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0
/* MC_CMD_PORT_READ128_OUT msgresponse */
#define MC_CMD_PORT_READ128_OUT_LEN 20
+/* Value */
#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0
#define MC_CMD_PORT_READ128_OUT_VALUE_LEN 16
+/* Status */
#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16
/***********************************/
-/* MC_CMD_PORT_WRITE128
- * Write a 128-bit register to the indirect port register map.
+/* MC_CMD_PORT_WRITE128
+ * Write a 128-bit register to the indirect port register map. The port to
+ * access is implied by the Shared memory channel used.
*/
-#define MC_CMD_PORT_WRITE128 0x17
+#define MC_CMD_PORT_WRITE128 0x17
/* MC_CMD_PORT_WRITE128_IN msgrequest */
#define MC_CMD_PORT_WRITE128_IN_LEN 20
+/* Address */
#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0
+/* Value */
#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4
#define MC_CMD_PORT_WRITE128_IN_VALUE_LEN 16
/* MC_CMD_PORT_WRITE128_OUT msgresponse */
#define MC_CMD_PORT_WRITE128_OUT_LEN 4
+/* Status */
#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0
+/* MC_CMD_CAPABILITIES structuredef */
+#define MC_CMD_CAPABILITIES_LEN 4
+/* Small buf table. */
+#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_LBN 0
+#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_WIDTH 1
+/* Turbo mode (for Maranello). */
+#define MC_CMD_CAPABILITIES_TURBO_LBN 1
+#define MC_CMD_CAPABILITIES_TURBO_WIDTH 1
+/* Turbo mode active (for Maranello). */
+#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN 2
+#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_WIDTH 1
+/* PTP offload. */
+#define MC_CMD_CAPABILITIES_PTP_LBN 3
+#define MC_CMD_CAPABILITIES_PTP_WIDTH 1
+/* AOE mode. */
+#define MC_CMD_CAPABILITIES_AOE_LBN 4
+#define MC_CMD_CAPABILITIES_AOE_WIDTH 1
+/* AOE mode active. */
+#define MC_CMD_CAPABILITIES_AOE_ACTIVE_LBN 5
+#define MC_CMD_CAPABILITIES_AOE_ACTIVE_WIDTH 1
+/* AOE mode active. */
+#define MC_CMD_CAPABILITIES_FC_ACTIVE_LBN 6
+#define MC_CMD_CAPABILITIES_FC_ACTIVE_WIDTH 1
+#define MC_CMD_CAPABILITIES_RESERVED_LBN 7
+#define MC_CMD_CAPABILITIES_RESERVED_WIDTH 25
+
/***********************************/
-/* MC_CMD_GET_BOARD_CFG
+/* MC_CMD_GET_BOARD_CFG
* Returns the MC firmware configuration structure.
*/
-#define MC_CMD_GET_BOARD_CFG 0x18
+#define MC_CMD_GET_BOARD_CFG 0x18
+#undef MC_CMD_0x18_PRIVILEGE_CTG
+
+#define MC_CMD_0x18_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_BOARD_CFG_IN msgrequest */
#define MC_CMD_GET_BOARD_CFG_IN_LEN 0
@@ -2919,24 +4326,10 @@
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32
+/* See MC_CMD_CAPABILITIES */
#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36
-#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_LBN 0x0 /* enum */
-#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_TURBO_LBN 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_TURBO_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN 0x2 /* enum */
-#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_PTP_LBN 0x3 /* enum */
-#define MC_CMD_CAPABILITIES_PTP_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_AOE_LBN 0x4 /* enum */
-#define MC_CMD_CAPABILITIES_AOE_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_AOE_ACTIVE_LBN 0x5 /* enum */
-#define MC_CMD_CAPABILITIES_AOE_ACTIVE_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_FC_ACTIVE_LBN 0x6 /* enum */
-#define MC_CMD_CAPABILITIES_FC_ACTIVE_WIDTH 0x1 /* enum */
+/* See MC_CMD_CAPABILITIES */
#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40
-/* Enum values, see field(s): */
-/* CAPABILITIES_PORT0 */
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50
@@ -2945,6 +4338,11 @@
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68
+/* This field contains a 16-bit value for each of the types of NVRAM area. The
+ * values are defined in the firmware/mc/platform/.c file for a specific board
+ * type, but otherwise have no meaning to the MC; they are used by the driver
+ * to manage selection of appropriate firmware updates.
+ */
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 2
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM 12
@@ -2952,15 +4350,19 @@
/***********************************/
-/* MC_CMD_DBI_READX
- * Read DBI register(s).
+/* MC_CMD_DBI_READX
+ * Read DBI register(s) -- extended functionality
*/
-#define MC_CMD_DBI_READX 0x19
+#define MC_CMD_DBI_READX 0x19
+#undef MC_CMD_0x19_PRIVILEGE_CTG
+
+#define MC_CMD_0x19_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_DBI_READX_IN msgrequest */
#define MC_CMD_DBI_READX_IN_LENMIN 8
#define MC_CMD_DBI_READX_IN_LENMAX 248
#define MC_CMD_DBI_READX_IN_LEN(num) (0+8*(num))
+/* Each Read op consists of an address (offset 0), VF/CS2) */
#define MC_CMD_DBI_READX_IN_DBIRDOP_OFST 0
#define MC_CMD_DBI_READX_IN_DBIRDOP_LEN 8
#define MC_CMD_DBI_READX_IN_DBIRDOP_LO_OFST 0
@@ -2972,20 +4374,40 @@
#define MC_CMD_DBI_READX_OUT_LENMIN 4
#define MC_CMD_DBI_READX_OUT_LENMAX 252
#define MC_CMD_DBI_READX_OUT_LEN(num) (0+4*(num))
+/* Value */
#define MC_CMD_DBI_READX_OUT_VALUE_OFST 0
#define MC_CMD_DBI_READX_OUT_VALUE_LEN 4
#define MC_CMD_DBI_READX_OUT_VALUE_MINNUM 1
#define MC_CMD_DBI_READX_OUT_VALUE_MAXNUM 63
+/* MC_CMD_DBIRDOP_TYPEDEF structuredef */
+#define MC_CMD_DBIRDOP_TYPEDEF_LEN 8
+#define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_OFST 0
+#define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_LBN 0
+#define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_WIDTH 32
+#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_OFST 4
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_LBN 16
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_WIDTH 16
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_ACTIVE_LBN 15
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_ACTIVE_WIDTH 1
+#define MC_CMD_DBIRDOP_TYPEDEF_CS2_LBN 14
+#define MC_CMD_DBIRDOP_TYPEDEF_CS2_WIDTH 1
+#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_LBN 32
+#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_WIDTH 32
+
/***********************************/
-/* MC_CMD_SET_RAND_SEED
+/* MC_CMD_SET_RAND_SEED
* Set the 16byte seed for the MC pseudo-random generator.
*/
-#define MC_CMD_SET_RAND_SEED 0x1a
+#define MC_CMD_SET_RAND_SEED 0x1a
+#undef MC_CMD_0x1a_PRIVILEGE_CTG
+
+#define MC_CMD_0x1a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_RAND_SEED_IN msgrequest */
#define MC_CMD_SET_RAND_SEED_IN_LEN 16
+/* Seed value. */
#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0
#define MC_CMD_SET_RAND_SEED_IN_SEED_LEN 16
@@ -2994,10 +4416,10 @@
/***********************************/
-/* MC_CMD_LTSSM_HIST
- * Retrieve the history of the PCIE LTSSM.
+/* MC_CMD_LTSSM_HIST
+ * Retrieve the history of the LTSSM, if the build supports it.
*/
-#define MC_CMD_LTSSM_HIST 0x1b
+#define MC_CMD_LTSSM_HIST 0x1b
/* MC_CMD_LTSSM_HIST_IN msgrequest */
#define MC_CMD_LTSSM_HIST_IN_LEN 0
@@ -3006,6 +4428,7 @@
#define MC_CMD_LTSSM_HIST_OUT_LENMIN 0
#define MC_CMD_LTSSM_HIST_OUT_LENMAX 252
#define MC_CMD_LTSSM_HIST_OUT_LEN(num) (0+4*(num))
+/* variable number of LTSSM values, as bytes. The history is read-to-clear. */
#define MC_CMD_LTSSM_HIST_OUT_DATA_OFST 0
#define MC_CMD_LTSSM_HIST_OUT_DATA_LEN 4
#define MC_CMD_LTSSM_HIST_OUT_DATA_MINNUM 0
@@ -3013,29 +4436,72 @@
/***********************************/
-/* MC_CMD_DRV_ATTACH
- * Inform MCPU that this port is managed on the host.
+/* MC_CMD_DRV_ATTACH
+ * Inform MCPU that this port is managed on the host (i.e. driver active). For
+ * Huntington, also request the preferred datapath firmware to use if possible
+ * (it may not be possible for this request to be fulfilled; the driver must
+ * issue a subsequent MC_CMD_GET_CAPABILITIES command to determine which
+ * features are actually available). The FIRMWARE_ID field is ignored by older
+ * platforms.
*/
-#define MC_CMD_DRV_ATTACH 0x1c
+#define MC_CMD_DRV_ATTACH 0x1c
+#undef MC_CMD_0x1c_PRIVILEGE_CTG
+
+#define MC_CMD_0x1c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_DRV_ATTACH_IN msgrequest */
-#define MC_CMD_DRV_ATTACH_IN_LEN 8
+#define MC_CMD_DRV_ATTACH_IN_LEN 12
+/* new state (0=detached, 1=attached) to set if UPDATE=1 */
#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0
+/* 1 to set new state, or 0 to just report the existing state */
#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4
+/* preferred datapath firmware (for Huntington; ignored for Siena) */
+#define MC_CMD_DRV_ATTACH_IN_FIRMWARE_ID_OFST 8
+/* enum: Prefer to use full featured firmware */
+#define MC_CMD_FW_FULL_FEATURED 0x0
+/* enum: Prefer to use firmware with fewer features but lower latency */
+#define MC_CMD_FW_LOW_LATENCY 0x1
+/* enum: Prefer to use firmware for SolarCapture packed stream mode */
+#define MC_CMD_FW_PACKED_STREAM 0x2
+/* enum: Prefer to use firmware with fewer features and simpler TX event
+ * batching but higher TX packet rate
+ */
+#define MC_CMD_FW_HIGH_TX_RATE 0x3
+/* enum: Reserved value */
+#define MC_CMD_FW_PACKED_STREAM_HASH_MODE_1 0x4
+/* enum: Only this option is allowed for non-admin functions */
+#define MC_CMD_FW_DONT_CARE 0xffffffff
/* MC_CMD_DRV_ATTACH_OUT msgresponse */
#define MC_CMD_DRV_ATTACH_OUT_LEN 4
+/* previous or existing state (0=detached, 1=attached) */
#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0
+/* MC_CMD_DRV_ATTACH_EXT_OUT msgresponse */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_LEN 8
+/* previous or existing state (0=detached, 1=attached) */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_OLD_STATE_OFST 0
+/* Flags associated with this function */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FUNC_FLAGS_OFST 4
+/* enum: Labels the lowest-numbered function visible to the OS */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY 0x0
+/* enum: The function can control the link state of the physical port it is
+ * bound to.
+ */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL 0x1
+/* enum: The function can perform privileged operations */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED 0x2
+
/***********************************/
-/* MC_CMD_SHMUART
+/* MC_CMD_SHMUART
* Route UART output to circular buffer in shared memory instead.
*/
-#define MC_CMD_SHMUART 0x1f
+#define MC_CMD_SHMUART 0x1f
/* MC_CMD_SHMUART_IN msgrequest */
#define MC_CMD_SHMUART_IN_LEN 4
+/* ??? */
#define MC_CMD_SHMUART_IN_FLAG_OFST 0
/* MC_CMD_SHMUART_OUT msgresponse */
@@ -3043,10 +4509,15 @@
/***********************************/
-/* MC_CMD_PORT_RESET
- * Generic per-port reset.
+/* MC_CMD_PORT_RESET
+ * Generic per-port reset. There is no equivalent for per-board reset. Locks
+ * required: None; Return code: 0, ETIME. NOTE: This command is deprecated -
+ * use MC_CMD_ENTITY_RESET instead.
*/
-#define MC_CMD_PORT_RESET 0x20
+#define MC_CMD_PORT_RESET 0x20
+#undef MC_CMD_0x20_PRIVILEGE_CTG
+
+#define MC_CMD_0x20_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_PORT_RESET_IN msgrequest */
#define MC_CMD_PORT_RESET_IN_LEN 0
@@ -3056,14 +4527,38 @@
/***********************************/
-/* MC_CMD_PCIE_CREDITS
+/* MC_CMD_ENTITY_RESET
+ * Generic per-resource reset. There is no equivalent for per-board reset.
+ * Locks required: None; Return code: 0, ETIME. NOTE: This command is an
+ * extended version of the deprecated MC_CMD_PORT_RESET with added fields.
+ */
+#define MC_CMD_ENTITY_RESET 0x20
+/* MC_CMD_0x20_PRIVILEGE_CTG SRIOV_CTG_GENERAL */
+
+/* MC_CMD_ENTITY_RESET_IN msgrequest */
+#define MC_CMD_ENTITY_RESET_IN_LEN 4
+/* Optional flags field. Omitting this will perform a "legacy" reset action
+ * (TBD).
+ */
+#define MC_CMD_ENTITY_RESET_IN_FLAG_OFST 0
+#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_LBN 0
+#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_WIDTH 1
+
+/* MC_CMD_ENTITY_RESET_OUT msgresponse */
+#define MC_CMD_ENTITY_RESET_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_PCIE_CREDITS
* Read instantaneous and minimum flow control thresholds.
*/
-#define MC_CMD_PCIE_CREDITS 0x21
+#define MC_CMD_PCIE_CREDITS 0x21
/* MC_CMD_PCIE_CREDITS_IN msgrequest */
#define MC_CMD_PCIE_CREDITS_IN_LEN 8
+/* poll period. 0 is disabled */
#define MC_CMD_PCIE_CREDITS_IN_POLL_PERIOD_OFST 0
+/* wipe statistics */
#define MC_CMD_PCIE_CREDITS_IN_WIPE_OFST 4
/* MC_CMD_PCIE_CREDITS_OUT msgresponse */
@@ -3087,10 +4582,10 @@
/***********************************/
-/* MC_CMD_RXD_MONITOR
+/* MC_CMD_RXD_MONITOR
* Get histogram of RX queue fill level.
*/
-#define MC_CMD_RXD_MONITOR 0x22
+#define MC_CMD_RXD_MONITOR 0x22
/* MC_CMD_RXD_MONITOR_IN msgrequest */
#define MC_CMD_RXD_MONITOR_IN_LEN 12
@@ -3123,10 +4618,13 @@
/***********************************/
-/* MC_CMD_PUTS
- * puts(3) implementation over MCDI
+/* MC_CMD_PUTS
+ * Copy the given ASCII string out onto UART and/or out of the network port.
*/
-#define MC_CMD_PUTS 0x23
+#define MC_CMD_PUTS 0x23
+#undef MC_CMD_0x23_PRIVILEGE_CTG
+
+#define MC_CMD_0x23_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_PUTS_IN msgrequest */
#define MC_CMD_PUTS_IN_LENMIN 13
@@ -3149,16 +4647,21 @@
/***********************************/
-/* MC_CMD_GET_PHY_CFG
- * Report PHY configuration.
+/* MC_CMD_GET_PHY_CFG
+ * Report PHY configuration. This guarantees to succeed even if the PHY is in a
+ * 'zombie' state. Locks required: None
*/
-#define MC_CMD_GET_PHY_CFG 0x24
+#define MC_CMD_GET_PHY_CFG 0x24
+#undef MC_CMD_0x24_PRIVILEGE_CTG
+
+#define MC_CMD_0x24_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_PHY_CFG_IN msgrequest */
#define MC_CMD_GET_PHY_CFG_IN_LEN 0
/* MC_CMD_GET_PHY_CFG_OUT msgresponse */
#define MC_CMD_GET_PHY_CFG_OUT_LEN 72
+/* flags */
#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_LBN 0
#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_WIDTH 1
@@ -3174,7 +4677,9 @@
#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_WIDTH 1
#define MC_CMD_GET_PHY_CFG_OUT_BIST_LBN 6
#define MC_CMD_GET_PHY_CFG_OUT_BIST_WIDTH 1
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4
+/* Bitmask of supported capabilities */
#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8
#define MC_CMD_PHY_CAP_10HDX_LBN 1
#define MC_CMD_PHY_CAP_10HDX_WIDTH 1
@@ -3196,22 +4701,38 @@
#define MC_CMD_PHY_CAP_ASYM_WIDTH 1
#define MC_CMD_PHY_CAP_AN_LBN 10
#define MC_CMD_PHY_CAP_AN_WIDTH 1
+#define MC_CMD_PHY_CAP_40000FDX_LBN 11
+#define MC_CMD_PHY_CAP_40000FDX_WIDTH 1
#define MC_CMD_PHY_CAP_DDM_LBN 12
#define MC_CMD_PHY_CAP_DDM_WIDTH 1
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24
#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44
-#define MC_CMD_MEDIA_XAUI 0x1 /* enum */
-#define MC_CMD_MEDIA_CX4 0x2 /* enum */
-#define MC_CMD_MEDIA_KX4 0x3 /* enum */
-#define MC_CMD_MEDIA_XFP 0x4 /* enum */
-#define MC_CMD_MEDIA_SFP_PLUS 0x5 /* enum */
-#define MC_CMD_MEDIA_BASE_T 0x6 /* enum */
+/* enum: Xaui. */
+#define MC_CMD_MEDIA_XAUI 0x1
+/* enum: CX4. */
+#define MC_CMD_MEDIA_CX4 0x2
+/* enum: KX4. */
+#define MC_CMD_MEDIA_KX4 0x3
+/* enum: XFP Far. */
+#define MC_CMD_MEDIA_XFP 0x4
+/* enum: SFP+. */
+#define MC_CMD_MEDIA_SFP_PLUS 0x5
+/* enum: 10GBaseT. */
+#define MC_CMD_MEDIA_BASE_T 0x6
+/* enum: QSFP+. */
+#define MC_CMD_MEDIA_QSFP_PLUS 0x7
#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48
-#define MC_CMD_MMD_CLAUSE22 0x0 /* enum */
+/* enum: Native clause 22 */
+#define MC_CMD_MMD_CLAUSE22 0x0
#define MC_CMD_MMD_CLAUSE45_PMAPMD 0x1 /* enum */
#define MC_CMD_MMD_CLAUSE45_WIS 0x2 /* enum */
#define MC_CMD_MMD_CLAUSE45_PCS 0x3 /* enum */
@@ -3219,7 +4740,8 @@
#define MC_CMD_MMD_CLAUSE45_DTEXS 0x5 /* enum */
#define MC_CMD_MMD_CLAUSE45_TC 0x6 /* enum */
#define MC_CMD_MMD_CLAUSE45_AN 0x7 /* enum */
-#define MC_CMD_MMD_CLAUSE45_C22EXT 0x1d /* enum */
+/* enum: Clause22 proxied over clause45 by PHY. */
+#define MC_CMD_MMD_CLAUSE45_C22EXT 0x1d
#define MC_CMD_MMD_CLAUSE45_VEND1 0x1e /* enum */
#define MC_CMD_MMD_CLAUSE45_VEND2 0x1f /* enum */
#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52
@@ -3227,44 +4749,74 @@
/***********************************/
-/* MC_CMD_START_BIST
- * Start a BIST test on the PHY.
+/* MC_CMD_START_BIST
+ * Start a BIST test on the PHY. Locks required: PHY_LOCK if doing a PHY BIST
+ * Return code: 0, EINVAL, EACCES (if PHY_LOCK is not held)
*/
-#define MC_CMD_START_BIST 0x25
+#define MC_CMD_START_BIST 0x25
+#undef MC_CMD_0x25_PRIVILEGE_CTG
+
+#define MC_CMD_0x25_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_START_BIST_IN msgrequest */
#define MC_CMD_START_BIST_IN_LEN 4
+/* Type of test. */
#define MC_CMD_START_BIST_IN_TYPE_OFST 0
-#define MC_CMD_PHY_BIST_CABLE_SHORT 0x1 /* enum */
-#define MC_CMD_PHY_BIST_CABLE_LONG 0x2 /* enum */
-#define MC_CMD_BPX_SERDES_BIST 0x3 /* enum */
-#define MC_CMD_MC_LOOPBACK_BIST 0x4 /* enum */
-#define MC_CMD_PHY_BIST 0x5 /* enum */
+/* enum: Run the PHY's short cable BIST. */
+#define MC_CMD_PHY_BIST_CABLE_SHORT 0x1
+/* enum: Run the PHY's long cable BIST. */
+#define MC_CMD_PHY_BIST_CABLE_LONG 0x2
+/* enum: Run BIST on the currently selected BPX Serdes (XAUI or XFI) . */
+#define MC_CMD_BPX_SERDES_BIST 0x3
+/* enum: Run the MC loopback tests. */
+#define MC_CMD_MC_LOOPBACK_BIST 0x4
+/* enum: Run the PHY's standard BIST. */
+#define MC_CMD_PHY_BIST 0x5
+/* enum: Run MC RAM test. */
+#define MC_CMD_MC_MEM_BIST 0x6
+/* enum: Run Port RAM test. */
+#define MC_CMD_PORT_MEM_BIST 0x7
+/* enum: Run register test. */
+#define MC_CMD_REG_BIST 0x8
/* MC_CMD_START_BIST_OUT msgresponse */
#define MC_CMD_START_BIST_OUT_LEN 0
/***********************************/
-/* MC_CMD_POLL_BIST
- * Poll for BIST completion.
+/* MC_CMD_POLL_BIST
+ * Poll for BIST completion. Returns a single status code, and optionally some
+ * PHY specific bist output. The driver should only consume the BIST output
+ * after validating OUTLEN and MC_CMD_GET_PHY_CFG.TYPE. If a driver can't
+ * successfully parse the BIST output, it should still respect the pass/Fail in
+ * OUT.RESULT. Locks required: PHY_LOCK if doing a PHY BIST. Return code: 0,
+ * EACCES (if PHY_LOCK is not held).
*/
-#define MC_CMD_POLL_BIST 0x26
+#define MC_CMD_POLL_BIST 0x26
+#undef MC_CMD_0x26_PRIVILEGE_CTG
+
+#define MC_CMD_0x26_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_POLL_BIST_IN msgrequest */
#define MC_CMD_POLL_BIST_IN_LEN 0
/* MC_CMD_POLL_BIST_OUT msgresponse */
#define MC_CMD_POLL_BIST_OUT_LEN 8
+/* result */
#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0
-#define MC_CMD_POLL_BIST_RUNNING 0x1 /* enum */
-#define MC_CMD_POLL_BIST_PASSED 0x2 /* enum */
-#define MC_CMD_POLL_BIST_FAILED 0x3 /* enum */
-#define MC_CMD_POLL_BIST_TIMEOUT 0x4 /* enum */
+/* enum: Running. */
+#define MC_CMD_POLL_BIST_RUNNING 0x1
+/* enum: Passed. */
+#define MC_CMD_POLL_BIST_PASSED 0x2
+/* enum: Failed. */
+#define MC_CMD_POLL_BIST_FAILED 0x3
+/* enum: Timed-out. */
+#define MC_CMD_POLL_BIST_TIMEOUT 0x4
#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4
/* MC_CMD_POLL_BIST_OUT_SFT9001 msgresponse */
#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36
+/* result */
/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */
/* Enum values, see field(s): */
/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */
@@ -3272,44 +4824,118 @@
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16
+/* Status of each channel A */
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1 /* enum */
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 0x2 /* enum */
-#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 0x3 /* enum */
-#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 0x4 /* enum */
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9 /* enum */
+/* enum: Ok. */
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1
+/* enum: Open. */
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 0x2
+/* enum: Intra-pair short. */
+#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 0x3
+/* enum: Inter-pair short. */
+#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 0x4
+/* enum: Busy. */
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9
+/* Status of each channel B */
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24
/* Enum values, see field(s): */
/* CABLE_STATUS_A */
+/* Status of each channel C */
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28
/* Enum values, see field(s): */
/* CABLE_STATUS_A */
+/* Status of each channel D */
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32
/* Enum values, see field(s): */
/* CABLE_STATUS_A */
/* MC_CMD_POLL_BIST_OUT_MRSFP msgresponse */
#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8
+/* result */
/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */
/* Enum values, see field(s): */
/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */
#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4
-#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 0x1 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 0x2 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 0x3 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 0x4 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 0x5 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 0x6 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 0x7 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 0x8 /* enum */
+/* enum: Complete. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0
+/* enum: Bus switch off I2C write. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 0x1
+/* enum: Bus switch off I2C no access IO exp. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 0x2
+/* enum: Bus switch off I2C no access module. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 0x3
+/* enum: IO exp I2C configure. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 0x4
+/* enum: Bus switch I2C no cross talk. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 0x5
+/* enum: Module presence. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 0x6
+/* enum: Module ID I2C access. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 0x7
+/* enum: Module ID sane value. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 0x8
+
+/* MC_CMD_POLL_BIST_OUT_MEM msgresponse */
+#define MC_CMD_POLL_BIST_OUT_MEM_LEN 36
+/* result */
+/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */
+/* Enum values, see field(s): */
+/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */
+#define MC_CMD_POLL_BIST_OUT_MEM_TEST_OFST 4
+/* enum: Test has completed. */
+#define MC_CMD_POLL_BIST_MEM_COMPLETE 0x0
+/* enum: RAM test - walk ones. */
+#define MC_CMD_POLL_BIST_MEM_MEM_WALK_ONES 0x1
+/* enum: RAM test - walk zeros. */
+#define MC_CMD_POLL_BIST_MEM_MEM_WALK_ZEROS 0x2
+/* enum: RAM test - walking inversions zeros/ones. */
+#define MC_CMD_POLL_BIST_MEM_MEM_INV_ZERO_ONE 0x3
+/* enum: RAM test - walking inversions checkerboard. */
+#define MC_CMD_POLL_BIST_MEM_MEM_INV_CHKBOARD 0x4
+/* enum: Register test - set / clear individual bits. */
+#define MC_CMD_POLL_BIST_MEM_REG 0x5
+/* enum: ECC error detected. */
+#define MC_CMD_POLL_BIST_MEM_ECC 0x6
+/* Failure address, only valid if result is POLL_BIST_FAILED */
+#define MC_CMD_POLL_BIST_OUT_MEM_ADDR_OFST 8
+/* Bus or address space to which the failure address corresponds */
+#define MC_CMD_POLL_BIST_OUT_MEM_BUS_OFST 12
+/* enum: MC MIPS bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_MC 0x0
+/* enum: CSR IREG bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_CSR 0x1
+/* enum: RX DPCPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DPCPU_RX 0x2
+/* enum: TX0 DPCPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DPCPU_TX0 0x3
+/* enum: TX1 DPCPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DPCPU_TX1 0x4
+/* enum: RX DICPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DICPU_RX 0x5
+/* enum: TX DICPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DICPU_TX 0x6
+/* Pattern written to RAM / register */
+#define MC_CMD_POLL_BIST_OUT_MEM_EXPECT_OFST 16
+/* Actual value read from RAM / register */
+#define MC_CMD_POLL_BIST_OUT_MEM_ACTUAL_OFST 20
+/* ECC error mask */
+#define MC_CMD_POLL_BIST_OUT_MEM_ECC_OFST 24
+/* ECC parity error mask */
+#define MC_CMD_POLL_BIST_OUT_MEM_ECC_PARITY_OFST 28
+/* ECC fatal error mask */
+#define MC_CMD_POLL_BIST_OUT_MEM_ECC_FATAL_OFST 32
/***********************************/
-/* MC_CMD_FLUSH_RX_QUEUES
- * Flush receive queue(s).
+/* MC_CMD_FLUSH_RX_QUEUES
+ * Flush receive queue(s). If SRIOV is enabled (via MC_CMD_SRIOV), then RXQ
+ * flushes should be initiated via this MCDI operation, rather than via
+ * directly writing FLUSH_CMD.
+ *
+ * The flush is completed (either done/fail) asynchronously (after this command
+ * returns). The driver must still wait for flush done/failure events as usual.
*/
-#define MC_CMD_FLUSH_RX_QUEUES 0x27
+#define MC_CMD_FLUSH_RX_QUEUES 0x27
/* MC_CMD_FLUSH_RX_QUEUES_IN msgrequest */
#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMIN 4
@@ -3325,82 +4951,156 @@
/***********************************/
-/* MC_CMD_GET_LOOPBACK_MODES
- * Get port's loopback modes.
+/* MC_CMD_GET_LOOPBACK_MODES
+ * Returns a bitmask of loopback modes available at each speed.
*/
-#define MC_CMD_GET_LOOPBACK_MODES 0x28
+#define MC_CMD_GET_LOOPBACK_MODES 0x28
+#undef MC_CMD_0x28_PRIVILEGE_CTG
+
+#define MC_CMD_0x28_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_LOOPBACK_MODES_IN msgrequest */
#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0
/* MC_CMD_GET_LOOPBACK_MODES_OUT msgresponse */
-#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 40
+/* Supported loopbacks. */
#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_OFST 0
#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LEN 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LO_OFST 0
#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_HI_OFST 4
-#define MC_CMD_LOOPBACK_NONE 0x0 /* enum */
-#define MC_CMD_LOOPBACK_DATA 0x1 /* enum */
-#define MC_CMD_LOOPBACK_GMAC 0x2 /* enum */
-#define MC_CMD_LOOPBACK_XGMII 0x3 /* enum */
-#define MC_CMD_LOOPBACK_XGXS 0x4 /* enum */
-#define MC_CMD_LOOPBACK_XAUI 0x5 /* enum */
-#define MC_CMD_LOOPBACK_GMII 0x6 /* enum */
-#define MC_CMD_LOOPBACK_SGMII 0x7 /* enum */
-#define MC_CMD_LOOPBACK_XGBR 0x8 /* enum */
-#define MC_CMD_LOOPBACK_XFI 0x9 /* enum */
-#define MC_CMD_LOOPBACK_XAUI_FAR 0xa /* enum */
-#define MC_CMD_LOOPBACK_GMII_FAR 0xb /* enum */
-#define MC_CMD_LOOPBACK_SGMII_FAR 0xc /* enum */
-#define MC_CMD_LOOPBACK_XFI_FAR 0xd /* enum */
-#define MC_CMD_LOOPBACK_GPHY 0xe /* enum */
-#define MC_CMD_LOOPBACK_PHYXS 0xf /* enum */
-#define MC_CMD_LOOPBACK_PCS 0x10 /* enum */
-#define MC_CMD_LOOPBACK_PMAPMD 0x11 /* enum */
-#define MC_CMD_LOOPBACK_XPORT 0x12 /* enum */
-#define MC_CMD_LOOPBACK_XGMII_WS 0x13 /* enum */
-#define MC_CMD_LOOPBACK_XAUI_WS 0x14 /* enum */
-#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 /* enum */
-#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 /* enum */
-#define MC_CMD_LOOPBACK_GMII_WS 0x17 /* enum */
-#define MC_CMD_LOOPBACK_XFI_WS 0x18 /* enum */
-#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 /* enum */
-#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a /* enum */
-#define MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23 /* enum */
+/* enum: None. */
+#define MC_CMD_LOOPBACK_NONE 0x0
+/* enum: Data. */
+#define MC_CMD_LOOPBACK_DATA 0x1
+/* enum: GMAC. */
+#define MC_CMD_LOOPBACK_GMAC 0x2
+/* enum: XGMII. */
+#define MC_CMD_LOOPBACK_XGMII 0x3
+/* enum: XGXS. */
+#define MC_CMD_LOOPBACK_XGXS 0x4
+/* enum: XAUI. */
+#define MC_CMD_LOOPBACK_XAUI 0x5
+/* enum: GMII. */
+#define MC_CMD_LOOPBACK_GMII 0x6
+/* enum: SGMII. */
+#define MC_CMD_LOOPBACK_SGMII 0x7
+/* enum: XGBR. */
+#define MC_CMD_LOOPBACK_XGBR 0x8
+/* enum: XFI. */
+#define MC_CMD_LOOPBACK_XFI 0x9
+/* enum: XAUI Far. */
+#define MC_CMD_LOOPBACK_XAUI_FAR 0xa
+/* enum: GMII Far. */
+#define MC_CMD_LOOPBACK_GMII_FAR 0xb
+/* enum: SGMII Far. */
+#define MC_CMD_LOOPBACK_SGMII_FAR 0xc
+/* enum: XFI Far. */
+#define MC_CMD_LOOPBACK_XFI_FAR 0xd
+/* enum: GPhy. */
+#define MC_CMD_LOOPBACK_GPHY 0xe
+/* enum: PhyXS. */
+#define MC_CMD_LOOPBACK_PHYXS 0xf
+/* enum: PCS. */
+#define MC_CMD_LOOPBACK_PCS 0x10
+/* enum: PMA-PMD. */
+#define MC_CMD_LOOPBACK_PMAPMD 0x11
+/* enum: Cross-Port. */
+#define MC_CMD_LOOPBACK_XPORT 0x12
+/* enum: XGMII-Wireside. */
+#define MC_CMD_LOOPBACK_XGMII_WS 0x13
+/* enum: XAUI Wireside. */
+#define MC_CMD_LOOPBACK_XAUI_WS 0x14
+/* enum: XAUI Wireside Far. */
+#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15
+/* enum: XAUI Wireside near. */
+#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16
+/* enum: GMII Wireside. */
+#define MC_CMD_LOOPBACK_GMII_WS 0x17
+/* enum: XFI Wireside. */
+#define MC_CMD_LOOPBACK_XFI_WS 0x18
+/* enum: XFI Wireside Far. */
+#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19
+/* enum: PhyXS Wireside. */
+#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a
+/* enum: PMA lanes MAC-Serdes. */
+#define MC_CMD_LOOPBACK_PMA_INT 0x1b
+/* enum: KR Serdes Parallel (Encoder). */
+#define MC_CMD_LOOPBACK_SD_NEAR 0x1c
+/* enum: KR Serdes Serial. */
+#define MC_CMD_LOOPBACK_SD_FAR 0x1d
+/* enum: PMA lanes MAC-Serdes Wireside. */
+#define MC_CMD_LOOPBACK_PMA_INT_WS 0x1e
+/* enum: KR Serdes Parallel Wireside (Full PCS). */
+#define MC_CMD_LOOPBACK_SD_FEP2_WS 0x1f
+/* enum: KR Serdes Parallel Wireside (Sym Aligner to TX). */
+#define MC_CMD_LOOPBACK_SD_FEP1_5_WS 0x20
+/* enum: KR Serdes Parallel Wireside (Deserializer to Serializer). */
+#define MC_CMD_LOOPBACK_SD_FEP_WS 0x21
+/* enum: KR Serdes Serial Wireside. */
+#define MC_CMD_LOOPBACK_SD_FES_WS 0x22
+/* enum: Near side of AOE Siena side port */
+#define MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23
+/* enum: Medford Wireside datapath loopback */
+#define MC_CMD_LOOPBACK_DATA_WS 0x24
+/* enum: Force link up without setting up any physical loopback (snapper use
+ * only)
+ */
+#define MC_CMD_LOOPBACK_FORCE_EXT_LINK 0x25
+/* Supported loopbacks. */
#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LO_OFST 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_HI_OFST 12
/* Enum values, see field(s): */
/* 100M */
+/* Supported loopbacks. */
#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_OFST 16
#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LEN 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LO_OFST 16
#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_HI_OFST 20
/* Enum values, see field(s): */
/* 100M */
+/* Supported loopbacks. */
#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST 24
#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LO_OFST 24
#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_HI_OFST 28
/* Enum values, see field(s): */
/* 100M */
+/* Supported loopbacks. */
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST 32
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN 8
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LO_OFST 32
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_40G_HI_OFST 36
+/* Enum values, see field(s): */
+/* 100M */
/***********************************/
-/* MC_CMD_GET_LINK
- * Read the unified MAC/PHY link state.
+/* MC_CMD_GET_LINK
+ * Read the unified MAC/PHY link state. Locks required: None Return code: 0,
+ * ETIME.
*/
-#define MC_CMD_GET_LINK 0x29
+#define MC_CMD_GET_LINK 0x29
+#undef MC_CMD_0x29_PRIVILEGE_CTG
+
+#define MC_CMD_0x29_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_LINK_IN msgrequest */
#define MC_CMD_GET_LINK_IN_LEN 0
/* MC_CMD_GET_LINK_OUT msgresponse */
#define MC_CMD_GET_LINK_OUT_LEN 28
+/* near-side advertised capabilities */
#define MC_CMD_GET_LINK_OUT_CAP_OFST 0
+/* link-partner advertised capabilities */
#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4
+/* Autonegotiated speed in mbit/s. The link may still be down even if this
+ * reads non-zero.
+ */
#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8
+/* Current loopback setting. */
#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12
/* Enum values, see field(s): */
/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
@@ -3417,10 +5117,10 @@
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_RX_WIDTH 1
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_LBN 7
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_WIDTH 1
+/* This returns the negotiated flow control value. */
#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20
-#define MC_CMD_FCNTL_OFF 0x0 /* enum */
-#define MC_CMD_FCNTL_RESPOND 0x1 /* enum */
-#define MC_CMD_FCNTL_BIDIR 0x2 /* enum */
+/* Enum values, see field(s): */
+/* MC_CMD_SET_MAC/MC_CMD_SET_MAC_IN/FCNTL */
#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24
#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0
#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1
@@ -3433,14 +5133,20 @@
/***********************************/
-/* MC_CMD_SET_LINK
- * Write the unified MAC/PHY link configuration.
+/* MC_CMD_SET_LINK
+ * Write the unified MAC/PHY link configuration. Locks required: None. Return
+ * code: 0, EINVAL, ETIME
*/
-#define MC_CMD_SET_LINK 0x2a
+#define MC_CMD_SET_LINK 0x2a
+#undef MC_CMD_0x2a_PRIVILEGE_CTG
+
+#define MC_CMD_0x2a_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_SET_LINK_IN msgrequest */
#define MC_CMD_SET_LINK_IN_LEN 16
+/* ??? */
#define MC_CMD_SET_LINK_IN_CAP_OFST 0
+/* Flags */
#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4
#define MC_CMD_SET_LINK_IN_LOWPOWER_LBN 0
#define MC_CMD_SET_LINK_IN_LOWPOWER_WIDTH 1
@@ -3448,9 +5154,13 @@
#define MC_CMD_SET_LINK_IN_POWEROFF_WIDTH 1
#define MC_CMD_SET_LINK_IN_TXDIS_LBN 2
#define MC_CMD_SET_LINK_IN_TXDIS_WIDTH 1
+/* Loopback mode. */
#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8
/* Enum values, see field(s): */
/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
+/* A loopback speed of "0" is supported, and means (choose any available
+ * speed).
+ */
#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12
/* MC_CMD_SET_LINK_OUT msgresponse */
@@ -3458,13 +5168,17 @@
/***********************************/
-/* MC_CMD_SET_ID_LED
- * Set indentification LED state.
+/* MC_CMD_SET_ID_LED
+ * Set identification LED state. Locks required: None. Return code: 0, EINVAL
*/
-#define MC_CMD_SET_ID_LED 0x2b
+#define MC_CMD_SET_ID_LED 0x2b
+#undef MC_CMD_0x2b_PRIVILEGE_CTG
+
+#define MC_CMD_0x2b_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_SET_ID_LED_IN msgrequest */
#define MC_CMD_SET_ID_LED_IN_LEN 4
+/* Set LED state. */
#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0
#define MC_CMD_LED_OFF 0x0 /* enum */
#define MC_CMD_LED_ON 0x1 /* enum */
@@ -3475,13 +5189,19 @@
/***********************************/
-/* MC_CMD_SET_MAC
- * Set MAC configuration.
+/* MC_CMD_SET_MAC
+ * Set MAC configuration. Locks required: None. Return code: 0, EINVAL
*/
-#define MC_CMD_SET_MAC 0x2c
+#define MC_CMD_SET_MAC 0x2c
+#undef MC_CMD_0x2c_PRIVILEGE_CTG
+
+#define MC_CMD_0x2c_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_SET_MAC_IN msgrequest */
-#define MC_CMD_SET_MAC_IN_LEN 24
+#define MC_CMD_SET_MAC_IN_LEN 28
+/* The MTU is the MTU programmed directly into the XMAC/GMAC (inclusive of
+ * EtherII, VLAN, bug16011 padding).
+ */
#define MC_CMD_SET_MAC_IN_MTU_OFST 0
#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4
#define MC_CMD_SET_MAC_IN_ADDR_OFST 8
@@ -3494,23 +5214,43 @@
#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1
#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1
#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20
-/* MC_CMD_FCNTL_OFF 0x0 */
-/* MC_CMD_FCNTL_RESPOND 0x1 */
-/* MC_CMD_FCNTL_BIDIR 0x2 */
-#define MC_CMD_FCNTL_AUTO 0x3 /* enum */
+/* enum: Flow control is off. */
+#define MC_CMD_FCNTL_OFF 0x0
+/* enum: Respond to flow control. */
+#define MC_CMD_FCNTL_RESPOND 0x1
+/* enum: Respond to and Issue flow control. */
+#define MC_CMD_FCNTL_BIDIR 0x2
+/* enum: Auto neg flow control. */
+#define MC_CMD_FCNTL_AUTO 0x3
+/* enum: Priority flow control (eftest builds only). */
+#define MC_CMD_FCNTL_QBB 0x4
+/* enum: Issue flow control. */
+#define MC_CMD_FCNTL_GENERATE 0x5
+#define MC_CMD_SET_MAC_IN_FLAGS_OFST 24
+#define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_LBN 0
+#define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_WIDTH 1
/* MC_CMD_SET_MAC_OUT msgresponse */
#define MC_CMD_SET_MAC_OUT_LEN 0
/***********************************/
-/* MC_CMD_PHY_STATS
- * Get generic PHY statistics.
+/* MC_CMD_PHY_STATS
+ * Get generic PHY statistics. This call returns the statistics for a generic
+ * PHY in a sparse array (indexed by the enumerate). Each value is represented
+ * by a 32bit number. If the DMA_ADDR is 0, then no DMA is performed, and the
+ * statistics may be read from the message response. If DMA_ADDR != 0, then the
+ * statistics are dmad to that (page-aligned location). Locks required: None.
+ * Returns: 0, ETIME
*/
-#define MC_CMD_PHY_STATS 0x2d
+#define MC_CMD_PHY_STATS 0x2d
+#undef MC_CMD_0x2d_PRIVILEGE_CTG
+
+#define MC_CMD_0x2d_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_PHY_STATS_IN msgrequest */
#define MC_CMD_PHY_STATS_IN_LEN 8
+/* ??? */
#define MC_CMD_PHY_STATS_IN_DMA_ADDR_OFST 0
#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LEN 8
#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0
@@ -3524,40 +5264,75 @@
#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_OFST 0
#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_LEN 4
#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_PHY_NSTATS
-#define MC_CMD_OUI 0x0 /* enum */
-#define MC_CMD_PMA_PMD_LINK_UP 0x1 /* enum */
-#define MC_CMD_PMA_PMD_RX_FAULT 0x2 /* enum */
-#define MC_CMD_PMA_PMD_TX_FAULT 0x3 /* enum */
-#define MC_CMD_PMA_PMD_SIGNAL 0x4 /* enum */
-#define MC_CMD_PMA_PMD_SNR_A 0x5 /* enum */
-#define MC_CMD_PMA_PMD_SNR_B 0x6 /* enum */
-#define MC_CMD_PMA_PMD_SNR_C 0x7 /* enum */
-#define MC_CMD_PMA_PMD_SNR_D 0x8 /* enum */
-#define MC_CMD_PCS_LINK_UP 0x9 /* enum */
-#define MC_CMD_PCS_RX_FAULT 0xa /* enum */
-#define MC_CMD_PCS_TX_FAULT 0xb /* enum */
-#define MC_CMD_PCS_BER 0xc /* enum */
-#define MC_CMD_PCS_BLOCK_ERRORS 0xd /* enum */
-#define MC_CMD_PHYXS_LINK_UP 0xe /* enum */
-#define MC_CMD_PHYXS_RX_FAULT 0xf /* enum */
-#define MC_CMD_PHYXS_TX_FAULT 0x10 /* enum */
-#define MC_CMD_PHYXS_ALIGN 0x11 /* enum */
-#define MC_CMD_PHYXS_SYNC 0x12 /* enum */
-#define MC_CMD_AN_LINK_UP 0x13 /* enum */
-#define MC_CMD_AN_COMPLETE 0x14 /* enum */
-#define MC_CMD_AN_10GBT_STATUS 0x15 /* enum */
-#define MC_CMD_CL22_LINK_UP 0x16 /* enum */
-#define MC_CMD_PHY_NSTATS 0x17 /* enum */
-
-
-/***********************************/
-/* MC_CMD_MAC_STATS
- * Get generic MAC statistics.
- */
-#define MC_CMD_MAC_STATS 0x2e
+/* enum: OUI. */
+#define MC_CMD_OUI 0x0
+/* enum: PMA-PMD Link Up. */
+#define MC_CMD_PMA_PMD_LINK_UP 0x1
+/* enum: PMA-PMD RX Fault. */
+#define MC_CMD_PMA_PMD_RX_FAULT 0x2
+/* enum: PMA-PMD TX Fault. */
+#define MC_CMD_PMA_PMD_TX_FAULT 0x3
+/* enum: PMA-PMD Signal */
+#define MC_CMD_PMA_PMD_SIGNAL 0x4
+/* enum: PMA-PMD SNR A. */
+#define MC_CMD_PMA_PMD_SNR_A 0x5
+/* enum: PMA-PMD SNR B. */
+#define MC_CMD_PMA_PMD_SNR_B 0x6
+/* enum: PMA-PMD SNR C. */
+#define MC_CMD_PMA_PMD_SNR_C 0x7
+/* enum: PMA-PMD SNR D. */
+#define MC_CMD_PMA_PMD_SNR_D 0x8
+/* enum: PCS Link Up. */
+#define MC_CMD_PCS_LINK_UP 0x9
+/* enum: PCS RX Fault. */
+#define MC_CMD_PCS_RX_FAULT 0xa
+/* enum: PCS TX Fault. */
+#define MC_CMD_PCS_TX_FAULT 0xb
+/* enum: PCS BER. */
+#define MC_CMD_PCS_BER 0xc
+/* enum: PCS Block Errors. */
+#define MC_CMD_PCS_BLOCK_ERRORS 0xd
+/* enum: PhyXS Link Up. */
+#define MC_CMD_PHYXS_LINK_UP 0xe
+/* enum: PhyXS RX Fault. */
+#define MC_CMD_PHYXS_RX_FAULT 0xf
+/* enum: PhyXS TX Fault. */
+#define MC_CMD_PHYXS_TX_FAULT 0x10
+/* enum: PhyXS Align. */
+#define MC_CMD_PHYXS_ALIGN 0x11
+/* enum: PhyXS Sync. */
+#define MC_CMD_PHYXS_SYNC 0x12
+/* enum: AN link-up. */
+#define MC_CMD_AN_LINK_UP 0x13
+/* enum: AN Complete. */
+#define MC_CMD_AN_COMPLETE 0x14
+/* enum: AN 10GBaseT Status. */
+#define MC_CMD_AN_10GBT_STATUS 0x15
+/* enum: Clause 22 Link-Up. */
+#define MC_CMD_CL22_LINK_UP 0x16
+/* enum: (Last entry) */
+#define MC_CMD_PHY_NSTATS 0x17
+
+
+/***********************************/
+/* MC_CMD_MAC_STATS
+ * Get generic MAC statistics. This call returns unified statistics maintained
+ * by the MC as it switches between the GMAC and XMAC. The MC will write out
+ * all supported stats. The driver should zero initialise the buffer to
+ * guarantee consistent results. If the DMA_ADDR is 0, then no DMA is
+ * performed, and the statistics may be read from the message response. If
+ * DMA_ADDR != 0, then the statistics are dmad to that (page-aligned location).
+ * Locks required: None. The PERIODIC_CLEAR option is not used and now has no
+ * effect. Returns: 0, ETIME
+ */
+#define MC_CMD_MAC_STATS 0x2e
+#undef MC_CMD_0x2e_PRIVILEGE_CTG
+
+#define MC_CMD_0x2e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_MAC_STATS_IN msgrequest */
-#define MC_CMD_MAC_STATS_IN_LEN 16
+#define MC_CMD_MAC_STATS_IN_LEN 20
+/* ??? */
#define MC_CMD_MAC_STATS_IN_DMA_ADDR_OFST 0
#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LEN 8
#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0
@@ -3578,6 +5353,8 @@
#define MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16
#define MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16
#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12
+/* port id so vadapter stats can be provided */
+#define MC_CMD_MAC_STATS_IN_PORT_ID_OFST 16
/* MC_CMD_MAC_STATS_OUT_DMA msgresponse */
#define MC_CMD_MAC_STATS_OUT_DMA_LEN 0
@@ -3590,6 +5367,7 @@
#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_HI_OFST 4
#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS
#define MC_CMD_MAC_GENERATION_START 0x0 /* enum */
+#define MC_CMD_MAC_DMABUF_START 0x1 /* enum */
#define MC_CMD_MAC_TX_PKTS 0x1 /* enum */
#define MC_CMD_MAC_TX_PAUSE_PKTS 0x2 /* enum */
#define MC_CMD_MAC_TX_CONTROL_PKTS 0x3 /* enum */
@@ -3649,17 +5427,87 @@
#define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */
#define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */
#define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */
-#define MC_CMD_GMAC_DMABUF_START 0x40 /* enum */
-#define MC_CMD_GMAC_DMABUF_END 0x5f /* enum */
+/* enum: PM trunc_bb_overflow counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW 0x3c
+/* enum: PM discard_bb_overflow counter. Valid for EF10 with
+ * PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW 0x3d
+/* enum: PM trunc_vfifo_full counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_TRUNC_VFIFO_FULL 0x3e
+/* enum: PM discard_vfifo_full counter. Valid for EF10 with
+ * PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_PM_DISCARD_VFIFO_FULL 0x3f
+/* enum: PM trunc_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_TRUNC_QBB 0x40
+/* enum: PM discard_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_DISCARD_QBB 0x41
+/* enum: PM discard_mapping counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_DISCARD_MAPPING 0x42
+/* enum: RXDP counter: Number of packets dropped due to the queue being
+ * disabled. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_Q_DISABLED_PKTS 0x43
+/* enum: RXDP counter: Number of packets dropped by the DICPU. Valid for EF10
+ * with PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_DI_DROPPED_PKTS 0x45
+/* enum: RXDP counter: Number of non-host packets. Valid for EF10 with
+ * PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_STREAMING_PKTS 0x46
+/* enum: RXDP counter: Number of times an hlb descriptor fetch was performed.
+ * Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS 0x47
+/* enum: RXDP counter: Number of times the DPCPU waited for an existing
+ * descriptor fetch. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS 0x48
+#define MC_CMD_MAC_VADAPTER_RX_DMABUF_START 0x4c /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS 0x4c /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES 0x4d /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS 0x4e /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES 0x4f /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS 0x50 /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES 0x51 /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS 0x52 /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_BAD_BYTES 0x53 /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_OVERFLOW 0x54 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_DMABUF_START 0x57 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS 0x57 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES 0x58 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS 0x59 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES 0x5a /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS 0x5b /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES 0x5c /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS 0x5d /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_BAD_BYTES 0x5e /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_OVERFLOW 0x5f /* enum */
+/* enum: Start of GMAC stats buffer space, for Siena only. */
+#define MC_CMD_GMAC_DMABUF_START 0x40
+/* enum: End of GMAC stats buffer space, for Siena only. */
+#define MC_CMD_GMAC_DMABUF_END 0x5f
#define MC_CMD_MAC_GENERATION_END 0x60 /* enum */
#define MC_CMD_MAC_NSTATS 0x61 /* enum */
/***********************************/
-/* MC_CMD_SRIOV
+/* MC_CMD_SRIOV
* to be documented
*/
-#define MC_CMD_SRIOV 0x30
+#define MC_CMD_SRIOV 0x30
/* MC_CMD_SRIOV_IN msgrequest */
#define MC_CMD_SRIOV_IN_LEN 12
@@ -3674,6 +5522,7 @@
/* MC_CMD_MEMCPY_RECORD_TYPEDEF structuredef */
#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LEN 32
+/* this is only used for the first record */
#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_OFST 0
#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_LBN 0
#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_WIDTH 32
@@ -3702,15 +5551,32 @@
/***********************************/
-/* MC_CMD_MEMCPY
- * Perform memory copy operation.
+/* MC_CMD_MEMCPY
+ * DMA write data into (Rid,Addr), either by dma reading (Rid,Addr), or by data
+ * embedded directly in the command.
+ *
+ * A common pattern is for a client to use generation counts to signal a dma
+ * update of a datastructure. To facilitate this, this MCDI operation can
+ * contain multiple requests which are executed in strict order. Requests take
+ * the form of duplicating the entire MCDI request continuously (including the
+ * requests record, which is ignored in all but the first structure)
+ *
+ * The source data can either come from a DMA from the host, or it can be
+ * embedded within the request directly, thereby eliminating a DMA read. To
+ * indicate this, the client sets FROM_RID=%RID_INLINE, ADDR_HI=0, and
+ * ADDR_LO=offset, and inserts the data at %offset from the start of the
+ * payload. It's the callers responsibility to ensure that the embedded data
+ * doesn't overlap the records.
+ *
+ * Returns: 0, EINVAL (invalid RID)
*/
-#define MC_CMD_MEMCPY 0x31
+#define MC_CMD_MEMCPY 0x31
/* MC_CMD_MEMCPY_IN msgrequest */
#define MC_CMD_MEMCPY_IN_LENMIN 32
#define MC_CMD_MEMCPY_IN_LENMAX 224
#define MC_CMD_MEMCPY_IN_LEN(num) (0+32*(num))
+/* see MC_CMD_MEMCPY_RECORD_TYPEDEF */
#define MC_CMD_MEMCPY_IN_RECORD_OFST 0
#define MC_CMD_MEMCPY_IN_RECORD_LEN 32
#define MC_CMD_MEMCPY_IN_RECORD_MINNUM 1
@@ -3721,24 +5587,35 @@
/***********************************/
-/* MC_CMD_WOL_FILTER_SET
+/* MC_CMD_WOL_FILTER_SET
* Set a WoL filter.
*/
-#define MC_CMD_WOL_FILTER_SET 0x32
+#define MC_CMD_WOL_FILTER_SET 0x32
+#undef MC_CMD_0x32_PRIVILEGE_CTG
+
+#define MC_CMD_0x32_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_WOL_FILTER_SET_IN msgrequest */
#define MC_CMD_WOL_FILTER_SET_IN_LEN 192
#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0
#define MC_CMD_FILTER_MODE_SIMPLE 0x0 /* enum */
#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */
+/* A type value of 1 is unused. */
#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4
-#define MC_CMD_WOL_TYPE_MAGIC 0x0 /* enum */
-#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 /* enum */
-#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3 /* enum */
-#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4 /* enum */
-#define MC_CMD_WOL_TYPE_BITMAP 0x5 /* enum */
-#define MC_CMD_WOL_TYPE_LINK 0x6 /* enum */
-#define MC_CMD_WOL_TYPE_MAX 0x7 /* enum */
+/* enum: Magic */
+#define MC_CMD_WOL_TYPE_MAGIC 0x0
+/* enum: MS Windows Magic */
+#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2
+/* enum: IPv4 Syn */
+#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3
+/* enum: IPv6 Syn */
+#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4
+/* enum: Bitmap */
+#define MC_CMD_WOL_TYPE_BITMAP 0x5
+/* enum: Link */
+#define MC_CMD_WOL_TYPE_LINK 0x6
+/* enum: (Above this for future use) */
+#define MC_CMD_WOL_TYPE_MAX 0x7
#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8
#define MC_CMD_WOL_FILTER_SET_IN_DATA_LEN 4
#define MC_CMD_WOL_FILTER_SET_IN_DATA_NUM 46
@@ -3807,10 +5684,13 @@
/***********************************/
-/* MC_CMD_WOL_FILTER_REMOVE
- * Remove a WoL filter.
+/* MC_CMD_WOL_FILTER_REMOVE
+ * Remove a WoL filter. Locks required: None. Returns: 0, EINVAL, ENOSYS
*/
-#define MC_CMD_WOL_FILTER_REMOVE 0x33
+#define MC_CMD_WOL_FILTER_REMOVE 0x33
+#undef MC_CMD_0x33_PRIVILEGE_CTG
+
+#define MC_CMD_0x33_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_WOL_FILTER_REMOVE_IN msgrequest */
#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4
@@ -3821,10 +5701,14 @@
/***********************************/
-/* MC_CMD_WOL_FILTER_RESET
- * Reset (i.e. remove all) WoL filters.
+/* MC_CMD_WOL_FILTER_RESET
+ * Reset (i.e. remove all) WoL filters. Locks required: None. Returns: 0,
+ * ENOSYS
*/
-#define MC_CMD_WOL_FILTER_RESET 0x34
+#define MC_CMD_WOL_FILTER_RESET 0x34
+#undef MC_CMD_0x34_PRIVILEGE_CTG
+
+#define MC_CMD_0x34_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_WOL_FILTER_RESET_IN msgrequest */
#define MC_CMD_WOL_FILTER_RESET_IN_LEN 4
@@ -3837,10 +5721,10 @@
/***********************************/
-/* MC_CMD_SET_MCAST_HASH
- * Set the MCASH hash value.
+/* MC_CMD_SET_MCAST_HASH
+ * Set the MCAST hash value without otherwise reconfiguring the MAC
*/
-#define MC_CMD_SET_MCAST_HASH 0x35
+#define MC_CMD_SET_MCAST_HASH 0x35
/* MC_CMD_SET_MCAST_HASH_IN msgrequest */
#define MC_CMD_SET_MCAST_HASH_IN_LEN 32
@@ -3854,45 +5738,75 @@
/***********************************/
-/* MC_CMD_NVRAM_TYPES
- * Get virtual NVRAM partitions information.
+/* MC_CMD_NVRAM_TYPES
+ * Return bitfield indicating available types of virtual NVRAM partitions.
+ * Locks required: none. Returns: 0
*/
-#define MC_CMD_NVRAM_TYPES 0x36
+#define MC_CMD_NVRAM_TYPES 0x36
+#undef MC_CMD_0x36_PRIVILEGE_CTG
+
+#define MC_CMD_0x36_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_TYPES_IN msgrequest */
#define MC_CMD_NVRAM_TYPES_IN_LEN 0
/* MC_CMD_NVRAM_TYPES_OUT msgresponse */
#define MC_CMD_NVRAM_TYPES_OUT_LEN 4
+/* Bit mask of supported types. */
#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0
-#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0 /* enum */
-#define MC_CMD_NVRAM_TYPE_MC_FW 0x1 /* enum */
-#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 0x2 /* enum */
-#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 0x3 /* enum */
-#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 0x4 /* enum */
-#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 0x5 /* enum */
-#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 0x6 /* enum */
-#define MC_CMD_NVRAM_TYPE_EXP_ROM 0x7 /* enum */
-#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 0x8 /* enum */
-#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 0x9 /* enum */
-#define MC_CMD_NVRAM_TYPE_PHY_PORT0 0xa /* enum */
-#define MC_CMD_NVRAM_TYPE_PHY_PORT1 0xb /* enum */
-#define MC_CMD_NVRAM_TYPE_LOG 0xc /* enum */
-#define MC_CMD_NVRAM_TYPE_FPGA 0xd /* enum */
-#define MC_CMD_NVRAM_TYPE_FPGA_BACKUP 0xe /* enum */
-#define MC_CMD_NVRAM_TYPE_FC_FW 0xf /* enum */
-#define MC_CMD_NVRAM_TYPE_FC_FW_BACKUP 0x10 /* enum */
-#define MC_CMD_NVRAM_TYPE_CPLD 0x11 /* enum */
-#define MC_CMD_NVRAM_TYPE_LICENSE 0x12 /* enum */
-#define MC_CMD_NVRAM_TYPE_FC_LOG 0x13 /* enum */
-#define MC_CMD_NVRAM_TYPE_FC_EXTRA 0x14 /* enum */
-
-
-/***********************************/
-/* MC_CMD_NVRAM_INFO
- * Read info about a virtual NVRAM partition.
- */
-#define MC_CMD_NVRAM_INFO 0x37
+/* enum: Disabled callisto. */
+#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0
+/* enum: MC firmware. */
+#define MC_CMD_NVRAM_TYPE_MC_FW 0x1
+/* enum: MC backup firmware. */
+#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 0x2
+/* enum: Static configuration Port0. */
+#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 0x3
+/* enum: Static configuration Port1. */
+#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 0x4
+/* enum: Dynamic configuration Port0. */
+#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 0x5
+/* enum: Dynamic configuration Port1. */
+#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 0x6
+/* enum: Expansion Rom. */
+#define MC_CMD_NVRAM_TYPE_EXP_ROM 0x7
+/* enum: Expansion Rom Configuration Port0. */
+#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 0x8
+/* enum: Expansion Rom Configuration Port1. */
+#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 0x9
+/* enum: Phy Configuration Port0. */
+#define MC_CMD_NVRAM_TYPE_PHY_PORT0 0xa
+/* enum: Phy Configuration Port1. */
+#define MC_CMD_NVRAM_TYPE_PHY_PORT1 0xb
+/* enum: Log. */
+#define MC_CMD_NVRAM_TYPE_LOG 0xc
+/* enum: FPGA image. */
+#define MC_CMD_NVRAM_TYPE_FPGA 0xd
+/* enum: FPGA backup image */
+#define MC_CMD_NVRAM_TYPE_FPGA_BACKUP 0xe
+/* enum: FC firmware. */
+#define MC_CMD_NVRAM_TYPE_FC_FW 0xf
+/* enum: FC backup firmware. */
+#define MC_CMD_NVRAM_TYPE_FC_FW_BACKUP 0x10
+/* enum: CPLD image. */
+#define MC_CMD_NVRAM_TYPE_CPLD 0x11
+/* enum: Licensing information. */
+#define MC_CMD_NVRAM_TYPE_LICENSE 0x12
+/* enum: FC Log. */
+#define MC_CMD_NVRAM_TYPE_FC_LOG 0x13
+/* enum: Additional flash on FPGA. */
+#define MC_CMD_NVRAM_TYPE_FC_EXTRA 0x14
+
+
+/***********************************/
+/* MC_CMD_NVRAM_INFO
+ * Read info about a virtual NVRAM partition. Locks required: none. Returns: 0,
+ * EINVAL (bad type).
+ */
+#define MC_CMD_NVRAM_INFO 0x37
+#undef MC_CMD_0x37_PRIVILEGE_CTG
+
+#define MC_CMD_0x37_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_INFO_IN msgrequest */
#define MC_CMD_NVRAM_INFO_IN_LEN 4
@@ -3910,15 +5824,24 @@
#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN 0
#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_TLV_LBN 1
+#define MC_CMD_NVRAM_INFO_OUT_TLV_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_A_B_LBN 7
+#define MC_CMD_NVRAM_INFO_OUT_A_B_WIDTH 1
#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16
#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20
/***********************************/
-/* MC_CMD_NVRAM_UPDATE_START
- * Start a group of update operations on a virtual NVRAM partition.
+/* MC_CMD_NVRAM_UPDATE_START
+ * Start a group of update operations on a virtual NVRAM partition. Locks
+ * required: PHY_LOCK if type==*PHY*. Returns: 0, EINVAL (bad type), EACCES (if
+ * PHY_LOCK required and not held).
*/
-#define MC_CMD_NVRAM_UPDATE_START 0x38
+#define MC_CMD_NVRAM_UPDATE_START 0x38
+#undef MC_CMD_0x38_PRIVILEGE_CTG
+
+#define MC_CMD_0x38_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_UPDATE_START_IN msgrequest */
#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4
@@ -3931,10 +5854,15 @@
/***********************************/
-/* MC_CMD_NVRAM_READ
- * Read data from a virtual NVRAM partition.
+/* MC_CMD_NVRAM_READ
+ * Read data from a virtual NVRAM partition. Locks required: PHY_LOCK if
+ * type==*PHY*. Returns: 0, EINVAL (bad type/offset/length), EACCES (if
+ * PHY_LOCK required and not held)
*/
-#define MC_CMD_NVRAM_READ 0x39
+#define MC_CMD_NVRAM_READ 0x39
+#undef MC_CMD_0x39_PRIVILEGE_CTG
+
+#define MC_CMD_0x39_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_READ_IN msgrequest */
#define MC_CMD_NVRAM_READ_IN_LEN 12
@@ -3942,6 +5870,7 @@
/* Enum values, see field(s): */
/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4
+/* amount to read in bytes */
#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8
/* MC_CMD_NVRAM_READ_OUT msgresponse */
@@ -3955,10 +5884,15 @@
/***********************************/
-/* MC_CMD_NVRAM_WRITE
- * Write data to a virtual NVRAM partition.
+/* MC_CMD_NVRAM_WRITE
+ * Write data to a virtual NVRAM partition. Locks required: PHY_LOCK if
+ * type==*PHY*. Returns: 0, EINVAL (bad type/offset/length), EACCES (if
+ * PHY_LOCK required and not held)
*/
-#define MC_CMD_NVRAM_WRITE 0x3a
+#define MC_CMD_NVRAM_WRITE 0x3a
+#undef MC_CMD_0x3a_PRIVILEGE_CTG
+
+#define MC_CMD_0x3a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_WRITE_IN msgrequest */
#define MC_CMD_NVRAM_WRITE_IN_LENMIN 13
@@ -3979,10 +5913,15 @@
/***********************************/
-/* MC_CMD_NVRAM_ERASE
- * Erase sector(s) from a virtual NVRAM partition.
+/* MC_CMD_NVRAM_ERASE
+ * Erase sector(s) from a virtual NVRAM partition. Locks required: PHY_LOCK if
+ * type==*PHY*. Returns: 0, EINVAL (bad type/offset/length), EACCES (if
+ * PHY_LOCK required and not held)
*/
-#define MC_CMD_NVRAM_ERASE 0x3b
+#define MC_CMD_NVRAM_ERASE 0x3b
+#undef MC_CMD_0x3b_PRIVILEGE_CTG
+
+#define MC_CMD_0x3b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_ERASE_IN msgrequest */
#define MC_CMD_NVRAM_ERASE_IN_LEN 12
@@ -3997,10 +5936,15 @@
/***********************************/
-/* MC_CMD_NVRAM_UPDATE_FINISH
- * Finish a group of update operations on a virtual NVRAM partition.
+/* MC_CMD_NVRAM_UPDATE_FINISH
+ * Finish a group of update operations on a virtual NVRAM partition. Locks
+ * required: PHY_LOCK if type==*PHY*. Returns: 0, EINVAL (bad
+ * type/offset/length), EACCES (if PHY_LOCK required and not held)
*/
-#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
+#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
+#undef MC_CMD_0x3c_PRIVILEGE_CTG
+
+#define MC_CMD_0x3c_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_UPDATE_FINISH_IN msgrequest */
#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8
@@ -4014,10 +5958,27 @@
/***********************************/
-/* MC_CMD_REBOOT
+/* MC_CMD_REBOOT
* Reboot the MC.
+ *
+ * The AFTER_ASSERTION flag is intended to be used when the driver notices an
+ * assertion failure (at which point it is expected to perform a complete tear
+ * down and reinitialise), to allow both ports to reset the MC once in an
+ * atomic fashion.
+ *
+ * Production mc firmwares are generally compiled with REBOOT_ON_ASSERT=1,
+ * which means that they will automatically reboot out of the assertion
+ * handler, so this is in practise an optional operation. It is still
+ * recommended that drivers execute this to support custom firmwares with
+ * REBOOT_ON_ASSERT=0.
+ *
+ * Locks required: NONE Returns: Nothing. You get back a response with ERR=1,
+ * DATALEN=0
*/
-#define MC_CMD_REBOOT 0x3d
+#define MC_CMD_REBOOT 0x3d
+#undef MC_CMD_0x3d_PRIVILEGE_CTG
+
+#define MC_CMD_0x3d_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_REBOOT_IN msgrequest */
#define MC_CMD_REBOOT_IN_LEN 4
@@ -4029,10 +5990,15 @@
/***********************************/
-/* MC_CMD_SCHEDINFO
- * Request scheduler info.
+/* MC_CMD_SCHEDINFO
+ * Request scheduler info. Locks required: NONE. Returns: An array of
+ * (timeslice,maximum overrun), one for each thread, in ascending order of
+ * thread address.
*/
-#define MC_CMD_SCHEDINFO 0x3e
+#define MC_CMD_SCHEDINFO 0x3e
+#undef MC_CMD_0x3e_PRIVILEGE_CTG
+
+#define MC_CMD_0x3e_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SCHEDINFO_IN msgrequest */
#define MC_CMD_SCHEDINFO_IN_LEN 0
@@ -4048,15 +6014,28 @@
/***********************************/
-/* MC_CMD_REBOOT_MODE
+/* MC_CMD_REBOOT_MODE
+ * Set the mode for the next MC reboot. Locks required: NONE. Sets the reboot
+ * mode to the specified value. Returns the old mode.
*/
-#define MC_CMD_REBOOT_MODE 0x3f
+#define MC_CMD_REBOOT_MODE 0x3f
+#undef MC_CMD_0x3f_PRIVILEGE_CTG
+
+#define MC_CMD_0x3f_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_REBOOT_MODE_IN msgrequest */
#define MC_CMD_REBOOT_MODE_IN_LEN 4
#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0
-#define MC_CMD_REBOOT_MODE_NORMAL 0x0 /* enum */
-#define MC_CMD_REBOOT_MODE_SNAPPER 0x3 /* enum */
+/* enum: Normal. */
+#define MC_CMD_REBOOT_MODE_NORMAL 0x0
+/* enum: Power-on Reset. */
+#define MC_CMD_REBOOT_MODE_POR 0x2
+/* enum: Snapper. */
+#define MC_CMD_REBOOT_MODE_SNAPPER 0x3
+/* enum: snapper fake POR */
+#define MC_CMD_REBOOT_MODE_SNAPPER_POR 0x4
+#define MC_CMD_REBOOT_MODE_IN_FAKE_LBN 7
+#define MC_CMD_REBOOT_MODE_IN_FAKE_WIDTH 1
/* MC_CMD_REBOOT_MODE_OUT msgresponse */
#define MC_CMD_REBOOT_MODE_OUT_LEN 4
@@ -4064,54 +6043,238 @@
/***********************************/
-/* MC_CMD_SENSOR_INFO
+/* MC_CMD_SENSOR_INFO
* Returns information about every available sensor.
+ *
+ * Each sensor has a single (16bit) value, and a corresponding state. The
+ * mapping between value and state is nominally determined by the MC, but may
+ * be implemented using up to 2 ranges per sensor.
+ *
+ * This call returns a mask (32bit) of the sensors that are supported by this
+ * platform, then an array of sensor information structures, in order of sensor
+ * type (but without gaps for unimplemented sensors). Each structure defines
+ * the ranges for the corresponding sensor. An unused range is indicated by
+ * equal limit values. If one range is used, a value outside that range results
+ * in STATE_FATAL. If two ranges are used, a value outside the second range
+ * results in STATE_FATAL while a value outside the first and inside the second
+ * range results in STATE_WARNING.
+ *
+ * Sensor masks and sensor information arrays are organised into pages. For
+ * backward compatibility, older host software can only use sensors in page 0.
+ * Bit 32 in the sensor mask was previously unused, and is no reserved for use
+ * as the next page flag.
+ *
+ * If the request does not contain a PAGE value then firmware will only return
+ * page 0 of sensor information, with bit 31 in the sensor mask cleared.
+ *
+ * If the request contains a PAGE value then firmware responds with the sensor
+ * mask and sensor information array for that page of sensors. In this case bit
+ * 31 in the mask is set if another page exists.
+ *
+ * Locks required: None Returns: 0
*/
-#define MC_CMD_SENSOR_INFO 0x41
+#define MC_CMD_SENSOR_INFO 0x41
+#undef MC_CMD_0x41_PRIVILEGE_CTG
+
+#define MC_CMD_0x41_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SENSOR_INFO_IN msgrequest */
#define MC_CMD_SENSOR_INFO_IN_LEN 0
+/* MC_CMD_SENSOR_INFO_EXT_IN msgrequest */
+#define MC_CMD_SENSOR_INFO_EXT_IN_LEN 4
+/* Which page of sensors to report.
+ *
+ * Page 0 contains sensors 0 to 30 (sensor 31 is the next page bit).
+ *
+ * Page 1 contains sensors 32 to 62 (sensor 63 is the next page bit). etc.
+ */
+#define MC_CMD_SENSOR_INFO_EXT_IN_PAGE_OFST 0
+
/* MC_CMD_SENSOR_INFO_OUT msgresponse */
-#define MC_CMD_SENSOR_INFO_OUT_LENMIN 12
+#define MC_CMD_SENSOR_INFO_OUT_LENMIN 4
#define MC_CMD_SENSOR_INFO_OUT_LENMAX 252
#define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num))
#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0
-#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0 /* enum */
-#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1 /* enum */
-#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2 /* enum */
-#define MC_CMD_SENSOR_PHY0_TEMP 0x3 /* enum */
-#define MC_CMD_SENSOR_PHY0_COOLING 0x4 /* enum */
-#define MC_CMD_SENSOR_PHY1_TEMP 0x5 /* enum */
-#define MC_CMD_SENSOR_PHY1_COOLING 0x6 /* enum */
-#define MC_CMD_SENSOR_IN_1V0 0x7 /* enum */
-#define MC_CMD_SENSOR_IN_1V2 0x8 /* enum */
-#define MC_CMD_SENSOR_IN_1V8 0x9 /* enum */
-#define MC_CMD_SENSOR_IN_2V5 0xa /* enum */
-#define MC_CMD_SENSOR_IN_3V3 0xb /* enum */
-#define MC_CMD_SENSOR_IN_12V0 0xc /* enum */
-#define MC_CMD_SENSOR_IN_1V2A 0xd /* enum */
-#define MC_CMD_SENSOR_IN_VREF 0xe /* enum */
-#define MC_CMD_SENSOR_OUT_VAOE 0xf /* enum */
-#define MC_CMD_SENSOR_AOE_TEMP 0x10 /* enum */
-#define MC_CMD_SENSOR_PSU_AOE_TEMP 0x11 /* enum */
-#define MC_CMD_SENSOR_PSU_TEMP 0x12 /* enum */
-#define MC_CMD_SENSOR_FAN_0 0x13 /* enum */
-#define MC_CMD_SENSOR_FAN_1 0x14 /* enum */
-#define MC_CMD_SENSOR_FAN_2 0x15 /* enum */
-#define MC_CMD_SENSOR_FAN_3 0x16 /* enum */
-#define MC_CMD_SENSOR_FAN_4 0x17 /* enum */
-#define MC_CMD_SENSOR_IN_VAOE 0x18 /* enum */
-#define MC_CMD_SENSOR_OUT_IAOE 0x19 /* enum */
-#define MC_CMD_SENSOR_IN_IAOE 0x1a /* enum */
-#define MC_CMD_SENSOR_NIC_POWER 0x1b /* enum */
+/* enum: Controller temperature: degC */
+#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0
+/* enum: Phy common temperature: degC */
+#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1
+/* enum: Controller cooling: bool */
+#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2
+/* enum: Phy 0 temperature: degC */
+#define MC_CMD_SENSOR_PHY0_TEMP 0x3
+/* enum: Phy 0 cooling: bool */
+#define MC_CMD_SENSOR_PHY0_COOLING 0x4
+/* enum: Phy 1 temperature: degC */
+#define MC_CMD_SENSOR_PHY1_TEMP 0x5
+/* enum: Phy 1 cooling: bool */
+#define MC_CMD_SENSOR_PHY1_COOLING 0x6
+/* enum: 1.0v power: mV */
+#define MC_CMD_SENSOR_IN_1V0 0x7
+/* enum: 1.2v power: mV */
+#define MC_CMD_SENSOR_IN_1V2 0x8
+/* enum: 1.8v power: mV */
+#define MC_CMD_SENSOR_IN_1V8 0x9
+/* enum: 2.5v power: mV */
+#define MC_CMD_SENSOR_IN_2V5 0xa
+/* enum: 3.3v power: mV */
+#define MC_CMD_SENSOR_IN_3V3 0xb
+/* enum: 12v power: mV */
+#define MC_CMD_SENSOR_IN_12V0 0xc
+/* enum: 1.2v analogue power: mV */
+#define MC_CMD_SENSOR_IN_1V2A 0xd
+/* enum: reference voltage: mV */
+#define MC_CMD_SENSOR_IN_VREF 0xe
+/* enum: AOE FPGA power: mV */
+#define MC_CMD_SENSOR_OUT_VAOE 0xf
+/* enum: AOE FPGA temperature: degC */
+#define MC_CMD_SENSOR_AOE_TEMP 0x10
+/* enum: AOE FPGA PSU temperature: degC */
+#define MC_CMD_SENSOR_PSU_AOE_TEMP 0x11
+/* enum: AOE PSU temperature: degC */
+#define MC_CMD_SENSOR_PSU_TEMP 0x12
+/* enum: Fan 0 speed: RPM */
+#define MC_CMD_SENSOR_FAN_0 0x13
+/* enum: Fan 1 speed: RPM */
+#define MC_CMD_SENSOR_FAN_1 0x14
+/* enum: Fan 2 speed: RPM */
+#define MC_CMD_SENSOR_FAN_2 0x15
+/* enum: Fan 3 speed: RPM */
+#define MC_CMD_SENSOR_FAN_3 0x16
+/* enum: Fan 4 speed: RPM */
+#define MC_CMD_SENSOR_FAN_4 0x17
+/* enum: AOE FPGA input power: mV */
+#define MC_CMD_SENSOR_IN_VAOE 0x18
+/* enum: AOE FPGA current: mA */
+#define MC_CMD_SENSOR_OUT_IAOE 0x19
+/* enum: AOE FPGA input current: mA */
+#define MC_CMD_SENSOR_IN_IAOE 0x1a
+/* enum: NIC power consumption: W */
+#define MC_CMD_SENSOR_NIC_POWER 0x1b
+/* enum: 0.9v power voltage: mV */
+#define MC_CMD_SENSOR_IN_0V9 0x1c
+/* enum: 0.9v power current: mA */
+#define MC_CMD_SENSOR_IN_I0V9 0x1d
+/* enum: 1.2v power current: mA */
+#define MC_CMD_SENSOR_IN_I1V2 0x1e
+/* enum: Not a sensor: reserved for the next page flag */
+#define MC_CMD_SENSOR_PAGE0_NEXT 0x1f
+/* enum: 0.9v power voltage (at ADC): mV */
+#define MC_CMD_SENSOR_IN_0V9_ADC 0x20
+/* enum: Controller temperature 2: degC */
+#define MC_CMD_SENSOR_CONTROLLER_2_TEMP 0x21
+/* enum: Voltage regulator internal temperature: degC */
+#define MC_CMD_SENSOR_VREG_INTERNAL_TEMP 0x22
+/* enum: 0.9V voltage regulator temperature: degC */
+#define MC_CMD_SENSOR_VREG_0V9_TEMP 0x23
+/* enum: 1.2V voltage regulator temperature: degC */
+#define MC_CMD_SENSOR_VREG_1V2_TEMP 0x24
+/* enum: controller internal temperature sensor voltage (internal ADC): mV */
+#define MC_CMD_SENSOR_CONTROLLER_VPTAT 0x25
+/* enum: controller internal temperature (internal ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP 0x26
+/* enum: controller internal temperature sensor voltage (external ADC): mV */
+#define MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC 0x27
+/* enum: controller internal temperature (external ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC 0x28
+/* enum: ambient temperature: degC */
+#define MC_CMD_SENSOR_AMBIENT_TEMP 0x29
+/* enum: air flow: bool */
+#define MC_CMD_SENSOR_AIRFLOW 0x2a
+/* enum: voltage between VSS08D and VSS08D at CSR: mV */
+#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR 0x2b
+/* enum: voltage between VSS08D and VSS08D at CSR (external ADC): mV */
+#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC 0x2c
+/* enum: Hotpoint temperature: degC */
+#define MC_CMD_SENSOR_HOTPOINT_TEMP 0x2d
+/* enum: Port 0 PHY power switch over-current: bool */
+#define MC_CMD_SENSOR_PHY_POWER_PORT0 0x2e
+/* enum: Port 1 PHY power switch over-current: bool */
+#define MC_CMD_SENSOR_PHY_POWER_PORT1 0x2f
+/* enum: Mop-up microcontroller reference voltage (millivolts) */
+#define MC_CMD_SENSOR_MUM_VCC 0x30
+/* enum: 0.9v power phase A voltage: mV */
+#define MC_CMD_SENSOR_IN_0V9_A 0x31
+/* enum: 0.9v power phase A current: mA */
+#define MC_CMD_SENSOR_IN_I0V9_A 0x32
+/* enum: 0.9V voltage regulator phase A temperature: degC */
+#define MC_CMD_SENSOR_VREG_0V9_A_TEMP 0x33
+/* enum: 0.9v power phase B voltage: mV */
+#define MC_CMD_SENSOR_IN_0V9_B 0x34
+/* enum: 0.9v power phase B current: mA */
+#define MC_CMD_SENSOR_IN_I0V9_B 0x35
+/* enum: 0.9V voltage regulator phase B temperature: degC */
+#define MC_CMD_SENSOR_VREG_0V9_B_TEMP 0x36
+/* enum: CCOM AVREG 1v2 supply (interval ADC): mV */
+#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY 0x37
+/* enum: CCOM AVREG 1v2 supply (external ADC): mV */
+#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC 0x38
+/* enum: CCOM AVREG 1v8 supply (interval ADC): mV */
+#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY 0x39
+/* enum: CCOM AVREG 1v8 supply (external ADC): mV */
+#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC 0x3a
+/* enum: Not a sensor: reserved for the next page flag */
+#define MC_CMD_SENSOR_PAGE1_NEXT 0x3f
+/* enum: controller internal temperature sensor voltage on master core
+ * (internal ADC): mV
+ */
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT 0x40
+/* enum: controller internal temperature on master core (internal ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP 0x41
+/* enum: controller internal temperature sensor voltage on master core
+ * (external ADC): mV
+ */
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC 0x42
+/* enum: controller internal temperature on master core (external ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC 0x43
+/* enum: controller internal temperature on slave core sensor voltage (internal
+ * ADC): mV
+ */
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT 0x44
+/* enum: controller internal temperature on slave core (internal ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP 0x45
+/* enum: controller internal temperature on slave core sensor voltage (external
+ * ADC): mV
+ */
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC 0x46
+/* enum: controller internal temperature on slave core (external ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC 0x47
+/* enum: Voltage supplied to the SODIMMs from their power supply: mV */
+#define MC_CMD_SENSOR_SODIMM_VOUT 0x49
+/* enum: Temperature of SODIMM 0 (if installed): degC */
+#define MC_CMD_SENSOR_SODIMM_0_TEMP 0x4a
+/* enum: Temperature of SODIMM 1 (if installed): degC */
+#define MC_CMD_SENSOR_SODIMM_1_TEMP 0x4b
+/* enum: Voltage supplied to the QSFP #0 from their power supply: mV */
+#define MC_CMD_SENSOR_PHY0_VCC 0x4c
+/* enum: Voltage supplied to the QSFP #1 from their power supply: mV */
+#define MC_CMD_SENSOR_PHY1_VCC 0x4d
+/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */
#define MC_CMD_SENSOR_ENTRY_OFST 4
#define MC_CMD_SENSOR_ENTRY_LEN 8
#define MC_CMD_SENSOR_ENTRY_LO_OFST 4
#define MC_CMD_SENSOR_ENTRY_HI_OFST 8
-#define MC_CMD_SENSOR_ENTRY_MINNUM 1
+#define MC_CMD_SENSOR_ENTRY_MINNUM 0
#define MC_CMD_SENSOR_ENTRY_MAXNUM 31
+/* MC_CMD_SENSOR_INFO_EXT_OUT msgresponse */
+#define MC_CMD_SENSOR_INFO_EXT_OUT_LENMIN 4
+#define MC_CMD_SENSOR_INFO_EXT_OUT_LENMAX 252
+#define MC_CMD_SENSOR_INFO_EXT_OUT_LEN(num) (4+8*(num))
+#define MC_CMD_SENSOR_INFO_EXT_OUT_MASK_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_SENSOR_INFO_OUT */
+#define MC_CMD_SENSOR_INFO_EXT_OUT_NEXT_PAGE_LBN 31
+#define MC_CMD_SENSOR_INFO_EXT_OUT_NEXT_PAGE_WIDTH 1
+/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */
+/* MC_CMD_SENSOR_ENTRY_OFST 4 */
+/* MC_CMD_SENSOR_ENTRY_LEN 8 */
+/* MC_CMD_SENSOR_ENTRY_LO_OFST 4 */
+/* MC_CMD_SENSOR_ENTRY_HI_OFST 8 */
+/* MC_CMD_SENSOR_ENTRY_MINNUM 0 */
+/* MC_CMD_SENSOR_ENTRY_MAXNUM 31 */
+
/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */
#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN 8
#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_OFST 0
@@ -4133,42 +6296,91 @@
/***********************************/
-/* MC_CMD_READ_SENSORS
- * Returns the current reading from each sensor.
+/* MC_CMD_READ_SENSORS
+ * Returns the current reading from each sensor. DMAs an array of sensor
+ * readings, in order of sensor type (but without gaps for unimplemented
+ * sensors), into host memory. Each array element is a
+ * MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF dword.
+ *
+ * If the request does not contain the LENGTH field then only sensors 0 to 30
+ * are reported, to avoid DMA buffer overflow in older host software. If the
+ * sensor reading require more space than the LENGTH allows, then return
+ * EINVAL.
+ *
+ * The MC will send a SENSOREVT event every time any sensor changes state. The
+ * driver is responsible for ensuring that it doesn't miss any events. The
+ * board will function normally if all sensors are in STATE_OK or
+ * STATE_WARNING. Otherwise the board should not be expected to function.
*/
-#define MC_CMD_READ_SENSORS 0x42
+#define MC_CMD_READ_SENSORS 0x42
+#undef MC_CMD_0x42_PRIVILEGE_CTG
+
+#define MC_CMD_0x42_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_READ_SENSORS_IN msgrequest */
#define MC_CMD_READ_SENSORS_IN_LEN 8
+/* DMA address of host buffer for sensor readings (must be 4Kbyte aligned). */
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_OFST 0
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LEN 8
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4
+/* MC_CMD_READ_SENSORS_EXT_IN msgrequest */
+#define MC_CMD_READ_SENSORS_EXT_IN_LEN 12
+/* DMA address of host buffer for sensor readings */
+#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_OFST 0
+#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_LEN 8
+#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_LO_OFST 0
+#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_HI_OFST 4
+/* Size in bytes of host buffer. */
+#define MC_CMD_READ_SENSORS_EXT_IN_LENGTH_OFST 8
+
/* MC_CMD_READ_SENSORS_OUT msgresponse */
#define MC_CMD_READ_SENSORS_OUT_LEN 0
+/* MC_CMD_READ_SENSORS_EXT_OUT msgresponse */
+#define MC_CMD_READ_SENSORS_EXT_OUT_LEN 0
+
/* MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF structuredef */
-#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN 3
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN 4
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_OFST 0
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LEN 2
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LBN 0
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_WIDTH 16
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_OFST 2
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LEN 1
-#define MC_CMD_SENSOR_STATE_OK 0x0 /* enum */
-#define MC_CMD_SENSOR_STATE_WARNING 0x1 /* enum */
-#define MC_CMD_SENSOR_STATE_FATAL 0x2 /* enum */
-#define MC_CMD_SENSOR_STATE_BROKEN 0x3 /* enum */
+/* enum: Ok. */
+#define MC_CMD_SENSOR_STATE_OK 0x0
+/* enum: Breached warning threshold. */
+#define MC_CMD_SENSOR_STATE_WARNING 0x1
+/* enum: Breached fatal threshold. */
+#define MC_CMD_SENSOR_STATE_FATAL 0x2
+/* enum: Fault with sensor. */
+#define MC_CMD_SENSOR_STATE_BROKEN 0x3
+/* enum: Sensor is working but does not currently have a reading. */
+#define MC_CMD_SENSOR_STATE_NO_READING 0x4
+/* enum: Sensor initialisation failed. */
+#define MC_CMD_SENSOR_STATE_INIT_FAILED 0x5
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LBN 16
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_WIDTH 8
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_OFST 3
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_LEN 1
+/* Enum values, see field(s): */
+/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_LBN 24
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_WIDTH 8
/***********************************/
-/* MC_CMD_GET_PHY_STATE
- * Report current state of PHY.
+/* MC_CMD_GET_PHY_STATE
+ * Report current state of PHY. A 'zombie' PHY is a PHY that has failed to boot
+ * (e.g. due to missing or corrupted firmware). Locks required: None. Return
+ * code: 0
*/
-#define MC_CMD_GET_PHY_STATE 0x43
+#define MC_CMD_GET_PHY_STATE 0x43
+#undef MC_CMD_0x43_PRIVILEGE_CTG
+
+#define MC_CMD_0x43_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_PHY_STATE_IN msgrequest */
#define MC_CMD_GET_PHY_STATE_IN_LEN 0
@@ -4176,15 +6388,18 @@
/* MC_CMD_GET_PHY_STATE_OUT msgresponse */
#define MC_CMD_GET_PHY_STATE_OUT_LEN 4
#define MC_CMD_GET_PHY_STATE_OUT_STATE_OFST 0
-#define MC_CMD_PHY_STATE_OK 0x1 /* enum */
-#define MC_CMD_PHY_STATE_ZOMBIE 0x2 /* enum */
+/* enum: Ok. */
+#define MC_CMD_PHY_STATE_OK 0x1
+/* enum: Faulty. */
+#define MC_CMD_PHY_STATE_ZOMBIE 0x2
/***********************************/
-/* MC_CMD_SETUP_8021QBB
- * 802.1Qbb control.
+/* MC_CMD_SETUP_8021QBB
+ * 802.1Qbb control. 8 Tx queues that map to priorities 0 - 7. Use all 1s to
+ * disable 802.Qbb for a given priority.
*/
-#define MC_CMD_SETUP_8021QBB 0x44
+#define MC_CMD_SETUP_8021QBB 0x44
/* MC_CMD_SETUP_8021QBB_IN msgrequest */
#define MC_CMD_SETUP_8021QBB_IN_LEN 32
@@ -4196,10 +6411,13 @@
/***********************************/
-/* MC_CMD_WOL_FILTER_GET
- * Retrieve ID of any WoL filters.
+/* MC_CMD_WOL_FILTER_GET
+ * Retrieve ID of any WoL filters. Locks required: None. Returns: 0, ENOSYS
*/
-#define MC_CMD_WOL_FILTER_GET 0x45
+#define MC_CMD_WOL_FILTER_GET 0x45
+#undef MC_CMD_0x45_PRIVILEGE_CTG
+
+#define MC_CMD_0x45_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_WOL_FILTER_GET_IN msgrequest */
#define MC_CMD_WOL_FILTER_GET_IN_LEN 0
@@ -4210,10 +6428,14 @@
/***********************************/
-/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD
- * Add a protocol offload to NIC for lights-out state.
+/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD
+ * Add a protocol offload to NIC for lights-out state. Locks required: None.
+ * Returns: 0, ENOSYS
*/
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46
+#undef MC_CMD_0x46_PRIVILEGE_CTG
+
+#define MC_CMD_0x46_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN msgrequest */
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMIN 8
@@ -4250,10 +6472,14 @@
/***********************************/
-/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD
- * Remove a protocol offload from NIC for lights-out state.
+/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD
+ * Remove a protocol offload from NIC for lights-out state. Locks required:
+ * None. Returns: 0, ENOSYS
*/
-#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47
+#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47
+#undef MC_CMD_0x47_PRIVILEGE_CTG
+
+#define MC_CMD_0x47_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN msgrequest */
#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8
@@ -4265,10 +6491,10 @@
/***********************************/
-/* MC_CMD_MAC_RESET_RESTORE
- * Restore MAC after block reset.
+/* MC_CMD_MAC_RESET_RESTORE
+ * Restore MAC after block reset. Locks required: None. Returns: 0.
*/
-#define MC_CMD_MAC_RESET_RESTORE 0x48
+#define MC_CMD_MAC_RESET_RESTORE 0x48
/* MC_CMD_MAC_RESET_RESTORE_IN msgrequest */
#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0
@@ -4278,9 +6504,15 @@
/***********************************/
-/* MC_CMD_TESTASSERT
+/* MC_CMD_TESTASSERT
+ * Deliberately trigger an assert-detonation in the firmware for testing
+ * purposes (i.e. to allow tests that the driver copes gracefully). Locks
+ * required: None Returns: 0
*/
-#define MC_CMD_TESTASSERT 0x49
+#define MC_CMD_TESTASSERT 0x49
+#undef MC_CMD_0x49_PRIVILEGE_CTG
+
+#define MC_CMD_0x49_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_TESTASSERT_IN msgrequest */
#define MC_CMD_TESTASSERT_IN_LEN 0
@@ -4290,26 +6522,74 @@
/***********************************/
-/* MC_CMD_WORKAROUND
- * Enable/Disable a given workaround.
+/* MC_CMD_WORKAROUND
+ * Enable/Disable a given workaround. The mcfw will return EINVAL if it doesn't
+ * understand the given workaround number - which should not be treated as a
+ * hard error by client code. This op does not imply any semantics about each
+ * workaround, that's between the driver and the mcfw on a per-workaround
+ * basis. Locks required: None. Returns: 0, EINVAL .
*/
-#define MC_CMD_WORKAROUND 0x4a
+#define MC_CMD_WORKAROUND 0x4a
+#undef MC_CMD_0x4a_PRIVILEGE_CTG
+
+#define MC_CMD_0x4a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_WORKAROUND_IN msgrequest */
#define MC_CMD_WORKAROUND_IN_LEN 8
+/* The enums here must correspond with those in MC_CMD_GET_WORKAROUND. */
#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0
-#define MC_CMD_WORKAROUND_BUG17230 0x1 /* enum */
+/* enum: Bug 17230 work around. */
+#define MC_CMD_WORKAROUND_BUG17230 0x1
+/* enum: Bug 35388 work around (unsafe EVQ writes). */
+#define MC_CMD_WORKAROUND_BUG35388 0x2
+/* enum: Bug35017 workaround (A64 tables must be identity map) */
+#define MC_CMD_WORKAROUND_BUG35017 0x3
+/* enum: Bug 41750 present (MC_CMD_TRIGGER_INTERRUPT won't work) */
+#define MC_CMD_WORKAROUND_BUG41750 0x4
+/* enum: Bug 42008 present (Interrupts can overtake associated events). Caution
+ * - before adding code that queries this workaround, remember that there's
+ * released Monza firmware that doesn't understand MC_CMD_WORKAROUND_BUG42008,
+ * and will hence (incorrectly) report that the bug doesn't exist.
+ */
+#define MC_CMD_WORKAROUND_BUG42008 0x5
+/* enum: Bug 26807 features present in firmware (multicast filter chaining)
+ * This feature cannot be turned on/off while there are any filters already
+ * present. The behaviour in such case depends on the acting client's privilege
+ * level. If the client has the admin privilege, then all functions that have
+ * filters installed will be FLRed and the FLR_DONE flag will be set. Otherwise
+ * the command will fail with MC_CMD_ERR_FILTERS_PRESENT.
+ */
+#define MC_CMD_WORKAROUND_BUG26807 0x6
+/* 0 = disable the workaround indicated by TYPE; any non-zero value = enable
+ * the workaround
+ */
#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4
/* MC_CMD_WORKAROUND_OUT msgresponse */
#define MC_CMD_WORKAROUND_OUT_LEN 0
+/* MC_CMD_WORKAROUND_EXT_OUT msgresponse: This response format will be used
+ * when (TYPE == MC_CMD_WORKAROUND_BUG26807)
+ */
+#define MC_CMD_WORKAROUND_EXT_OUT_LEN 4
+#define MC_CMD_WORKAROUND_EXT_OUT_FLAGS_OFST 0
+#define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN 0
+#define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_WIDTH 1
+
/***********************************/
-/* MC_CMD_GET_PHY_MEDIA_INFO
- * Read media-specific data from PHY.
+/* MC_CMD_GET_PHY_MEDIA_INFO
+ * Read media-specific data from PHY (e.g. SFP/SFP+ module ID information for
+ * SFP+ PHYs). The 'media type' can be found via GET_PHY_CFG
+ * (GET_PHY_CFG_OUT_MEDIA_TYPE); the valid 'page number' input values, and the
+ * output data, are interpreted on a per-type basis. For SFP+: PAGE=0 or 1
+ * returns a 128-byte block read from module I2C address 0xA0 offset 0 or 0x80.
+ * Anything else: currently undefined. Locks required: None. Return code: 0.
*/
-#define MC_CMD_GET_PHY_MEDIA_INFO 0x4b
+#define MC_CMD_GET_PHY_MEDIA_INFO 0x4b
+#undef MC_CMD_0x4b_PRIVILEGE_CTG
+
+#define MC_CMD_0x4b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_GET_PHY_MEDIA_INFO_IN msgrequest */
#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4
@@ -4319,6 +6599,7 @@
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 252
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num))
+/* in bytes */
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1
@@ -4327,10 +6608,14 @@
/***********************************/
-/* MC_CMD_NVRAM_TEST
- * Test a particular NVRAM partition.
+/* MC_CMD_NVRAM_TEST
+ * Test a particular NVRAM partition for valid contents (where "valid" depends
+ * on the type of partition).
*/
-#define MC_CMD_NVRAM_TEST 0x4c
+#define MC_CMD_NVRAM_TEST 0x4c
+#undef MC_CMD_0x4c_PRIVILEGE_CTG
+
+#define MC_CMD_0x4c_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_TEST_IN msgrequest */
#define MC_CMD_NVRAM_TEST_IN_LEN 4
@@ -4341,22 +6626,31 @@
/* MC_CMD_NVRAM_TEST_OUT msgresponse */
#define MC_CMD_NVRAM_TEST_OUT_LEN 4
#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0
-#define MC_CMD_NVRAM_TEST_PASS 0x0 /* enum */
-#define MC_CMD_NVRAM_TEST_FAIL 0x1 /* enum */
-#define MC_CMD_NVRAM_TEST_NOTSUPP 0x2 /* enum */
+/* enum: Passed. */
+#define MC_CMD_NVRAM_TEST_PASS 0x0
+/* enum: Failed. */
+#define MC_CMD_NVRAM_TEST_FAIL 0x1
+/* enum: Not supported. */
+#define MC_CMD_NVRAM_TEST_NOTSUPP 0x2
/***********************************/
-/* MC_CMD_MRSFP_TWEAK
- * Read status and/or set parameters for the 'mrsfp' driver.
+/* MC_CMD_MRSFP_TWEAK
+ * Read status and/or set parameters for the 'mrsfp' driver in mr_rusty builds.
+ * I2C I/O expander bits are always read; if equaliser parameters are supplied,
+ * they are configured first. Locks required: None. Return code: 0, EINVAL.
*/
-#define MC_CMD_MRSFP_TWEAK 0x4d
+#define MC_CMD_MRSFP_TWEAK 0x4d
/* MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG msgrequest */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_LEN 16
+/* 0-6 low->high de-emph. */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_LEVEL_OFST 0
+/* 0-8 low->high ref.V */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_DT_CFG_OFST 4
+/* 0-8 0-8 low->high boost */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_BOOST_OFST 8
+/* 0-8 low->high ref.V */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_DT_CFG_OFST 12
/* MC_CMD_MRSFP_TWEAK_IN_READ_ONLY msgrequest */
@@ -4364,27 +6658,41 @@
/* MC_CMD_MRSFP_TWEAK_OUT msgresponse */
#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12
+/* input bits */
#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0
+/* output bits */
#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4
+/* direction */
#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8
-#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0 /* enum */
-#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_IN 0x1 /* enum */
+/* enum: Out. */
+#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0
+/* enum: In. */
+#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_IN 0x1
/***********************************/
-/* MC_CMD_SENSOR_SET_LIMS
- * Adjusts the sensor limits.
+/* MC_CMD_SENSOR_SET_LIMS
+ * Adjusts the sensor limits. This is a warranty-voiding operation. Returns:
+ * ENOENT if the sensor specified does not exist, EINVAL if the limits are out
+ * of range.
*/
-#define MC_CMD_SENSOR_SET_LIMS 0x4e
+#define MC_CMD_SENSOR_SET_LIMS 0x4e
+#undef MC_CMD_0x4e_PRIVILEGE_CTG
+
+#define MC_CMD_0x4e_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SENSOR_SET_LIMS_IN msgrequest */
#define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20
#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0
/* Enum values, see field(s): */
/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */
+/* interpretation is is sensor-specific. */
#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4
+/* interpretation is is sensor-specific. */
#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8
+/* interpretation is is sensor-specific. */
#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12
+/* interpretation is is sensor-specific. */
#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16
/* MC_CMD_SENSOR_SET_LIMS_OUT msgresponse */
@@ -4392,9 +6700,9 @@
/***********************************/
-/* MC_CMD_GET_RESOURCE_LIMITS
+/* MC_CMD_GET_RESOURCE_LIMITS
*/
-#define MC_CMD_GET_RESOURCE_LIMITS 0x4f
+#define MC_CMD_GET_RESOURCE_LIMITS 0x4f
/* MC_CMD_GET_RESOURCE_LIMITS_IN msgrequest */
#define MC_CMD_GET_RESOURCE_LIMITS_IN_LEN 0
@@ -4408,19 +6716,129 @@
/***********************************/
-/* MC_CMD_CLP
- * CLP support operations
+/* MC_CMD_NVRAM_PARTITIONS
+ * Reads the list of available virtual NVRAM partition types. Locks required:
+ * none. Returns: 0, EINVAL (bad type).
+ */
+#define MC_CMD_NVRAM_PARTITIONS 0x51
+#undef MC_CMD_0x51_PRIVILEGE_CTG
+
+#define MC_CMD_0x51_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_NVRAM_PARTITIONS_IN msgrequest */
+#define MC_CMD_NVRAM_PARTITIONS_IN_LEN 0
+
+/* MC_CMD_NVRAM_PARTITIONS_OUT msgresponse */
+#define MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN 4
+#define MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX 252
+#define MC_CMD_NVRAM_PARTITIONS_OUT_LEN(num) (4+4*(num))
+/* total number of partitions */
+#define MC_CMD_NVRAM_PARTITIONS_OUT_NUM_PARTITIONS_OFST 0
+/* type ID code for each of NUM_PARTITIONS partitions */
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_OFST 4
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_LEN 4
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MINNUM 0
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MAXNUM 62
+
+
+/***********************************/
+/* MC_CMD_NVRAM_METADATA
+ * Reads soft metadata for a virtual NVRAM partition type. Locks required:
+ * none. Returns: 0, EINVAL (bad type).
+ */
+#define MC_CMD_NVRAM_METADATA 0x52
+#undef MC_CMD_0x52_PRIVILEGE_CTG
+
+#define MC_CMD_0x52_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_NVRAM_METADATA_IN msgrequest */
+#define MC_CMD_NVRAM_METADATA_IN_LEN 4
+/* Partition type ID code */
+#define MC_CMD_NVRAM_METADATA_IN_TYPE_OFST 0
+
+/* MC_CMD_NVRAM_METADATA_OUT msgresponse */
+#define MC_CMD_NVRAM_METADATA_OUT_LENMIN 20
+#define MC_CMD_NVRAM_METADATA_OUT_LENMAX 252
+#define MC_CMD_NVRAM_METADATA_OUT_LEN(num) (20+1*(num))
+/* Partition type ID code */
+#define MC_CMD_NVRAM_METADATA_OUT_TYPE_OFST 0
+#define MC_CMD_NVRAM_METADATA_OUT_FLAGS_OFST 4
+#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_LBN 0
+#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_WIDTH 1
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_LBN 1
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_WIDTH 1
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_LBN 2
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_WIDTH 1
+/* Subtype ID code for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_OFST 8
+/* 1st component of W.X.Y.Z version number for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_W_OFST 12
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_W_LEN 2
+/* 2nd component of W.X.Y.Z version number for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_X_OFST 14
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_X_LEN 2
+/* 3rd component of W.X.Y.Z version number for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_Y_OFST 16
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_Y_LEN 2
+/* 4th component of W.X.Y.Z version number for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_Z_OFST 18
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_Z_LEN 2
+/* Zero-terminated string describing the content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_OFST 20
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_LEN 1
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MINNUM 0
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM 232
+
+
+/***********************************/
+/* MC_CMD_GET_MAC_ADDRESSES
+ * Returns the base MAC, count and stride for the requesting function
*/
-#define MC_CMD_CLP 0x56
+#define MC_CMD_GET_MAC_ADDRESSES 0x55
+#undef MC_CMD_0x55_PRIVILEGE_CTG
+
+#define MC_CMD_0x55_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_MAC_ADDRESSES_IN msgrequest */
+#define MC_CMD_GET_MAC_ADDRESSES_IN_LEN 0
+
+/* MC_CMD_GET_MAC_ADDRESSES_OUT msgresponse */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_LEN 16
+/* Base MAC address */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE_OFST 0
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE_LEN 6
+/* Padding */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_RESERVED_OFST 6
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_RESERVED_LEN 2
+/* Number of allocated MAC addresses */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_COUNT_OFST 8
+/* Spacing of allocated MAC addresses */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_STRIDE_OFST 12
+
+
+/***********************************/
+/* MC_CMD_CLP
+ * Perform a CLP related operation
+ */
+#define MC_CMD_CLP 0x56
+#undef MC_CMD_0x56_PRIVILEGE_CTG
+
+#define MC_CMD_0x56_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_CLP_IN msgrequest */
#define MC_CMD_CLP_IN_LEN 4
+/* Sub operation */
#define MC_CMD_CLP_IN_OP_OFST 0
-#define MC_CMD_CLP_OP_DEFAULT 0x1 /* enum */
-#define MC_CMD_CLP_OP_SET_MAC 0x2 /* enum */
-#define MC_CMD_CLP_OP_GET_MAC 0x3 /* enum */
-#define MC_CMD_CLP_OP_SET_BOOT 0x4 /* enum */
-#define MC_CMD_CLP_OP_GET_BOOT 0x5 /* enum */
+/* enum: Return to factory default settings */
+#define MC_CMD_CLP_OP_DEFAULT 0x1
+/* enum: Set MAC address */
+#define MC_CMD_CLP_OP_SET_MAC 0x2
+/* enum: Get MAC address */
+#define MC_CMD_CLP_OP_GET_MAC 0x3
+/* enum: Set UEFI/GPXE boot mode */
+#define MC_CMD_CLP_OP_SET_BOOT 0x4
+/* enum: Get UEFI/GPXE boot mode */
+#define MC_CMD_CLP_OP_GET_BOOT 0x5
/* MC_CMD_CLP_OUT msgresponse */
#define MC_CMD_CLP_OUT_LEN 0
@@ -4435,8 +6853,10 @@
/* MC_CMD_CLP_IN_SET_MAC msgrequest */
#define MC_CMD_CLP_IN_SET_MAC_LEN 12
/* MC_CMD_CLP_IN_OP_OFST 0 */
+/* MAC address assigned to port */
#define MC_CMD_CLP_IN_SET_MAC_ADDR_OFST 4
#define MC_CMD_CLP_IN_SET_MAC_ADDR_LEN 6
+/* Padding */
#define MC_CMD_CLP_IN_SET_MAC_RESERVED_OFST 10
#define MC_CMD_CLP_IN_SET_MAC_RESERVED_LEN 2
@@ -4449,14 +6869,17 @@
/* MC_CMD_CLP_OUT_GET_MAC msgresponse */
#define MC_CMD_CLP_OUT_GET_MAC_LEN 8
+/* MAC address assigned to port */
#define MC_CMD_CLP_OUT_GET_MAC_ADDR_OFST 0
#define MC_CMD_CLP_OUT_GET_MAC_ADDR_LEN 6
+/* Padding */
#define MC_CMD_CLP_OUT_GET_MAC_RESERVED_OFST 6
#define MC_CMD_CLP_OUT_GET_MAC_RESERVED_LEN 2
/* MC_CMD_CLP_IN_SET_BOOT msgrequest */
#define MC_CMD_CLP_IN_SET_BOOT_LEN 5
/* MC_CMD_CLP_IN_OP_OFST 0 */
+/* Boot flag */
#define MC_CMD_CLP_IN_SET_BOOT_FLAG_OFST 4
#define MC_CMD_CLP_IN_SET_BOOT_FLAG_LEN 1
@@ -4469,113 +6892,920 @@
/* MC_CMD_CLP_OUT_GET_BOOT msgresponse */
#define MC_CMD_CLP_OUT_GET_BOOT_LEN 4
+/* Boot flag */
#define MC_CMD_CLP_OUT_GET_BOOT_FLAG_OFST 0
#define MC_CMD_CLP_OUT_GET_BOOT_FLAG_LEN 1
+/* Padding */
#define MC_CMD_CLP_OUT_GET_BOOT_RESERVED_OFST 1
#define MC_CMD_CLP_OUT_GET_BOOT_RESERVED_LEN 3
+
+/***********************************/
+/* MC_CMD_MUM
+ * Perform a MUM operation
+ */
+#define MC_CMD_MUM 0x57
+#undef MC_CMD_0x57_PRIVILEGE_CTG
+
+#define MC_CMD_0x57_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_MUM_IN msgrequest */
+#define MC_CMD_MUM_IN_LEN 4
+#define MC_CMD_MUM_IN_OP_HDR_OFST 0
+#define MC_CMD_MUM_IN_OP_LBN 0
+#define MC_CMD_MUM_IN_OP_WIDTH 8
+/* enum: NULL MCDI command to MUM */
+#define MC_CMD_MUM_OP_NULL 0x1
+/* enum: Get MUM version */
+#define MC_CMD_MUM_OP_GET_VERSION 0x2
+/* enum: Issue raw I2C command to MUM */
+#define MC_CMD_MUM_OP_RAW_CMD 0x3
+/* enum: Read from registers on devices connected to MUM. */
+#define MC_CMD_MUM_OP_READ 0x4
+/* enum: Write to registers on devices connected to MUM. */
+#define MC_CMD_MUM_OP_WRITE 0x5
+/* enum: Control UART logging. */
+#define MC_CMD_MUM_OP_LOG 0x6
+/* enum: Operations on MUM GPIO lines */
+#define MC_CMD_MUM_OP_GPIO 0x7
+/* enum: Get sensor readings from MUM */
+#define MC_CMD_MUM_OP_READ_SENSORS 0x8
+/* enum: Initiate clock programming on the MUM */
+#define MC_CMD_MUM_OP_PROGRAM_CLOCKS 0x9
+/* enum: Initiate FPGA load from flash on the MUM */
+#define MC_CMD_MUM_OP_FPGA_LOAD 0xa
+/* enum: Request sensor reading from MUM ADC resulting from earlier request via
+ * MUM ATB
+ */
+#define MC_CMD_MUM_OP_READ_ATB_SENSOR 0xb
+/* enum: Send commands relating to the QSFP ports via the MUM for PHY
+ * operations
+ */
+#define MC_CMD_MUM_OP_QSFP 0xc
+
+/* MC_CMD_MUM_IN_NULL msgrequest */
+#define MC_CMD_MUM_IN_NULL_LEN 4
+/* MUM cmd header */
+#define MC_CMD_MUM_IN_CMD_OFST 0
+
+/* MC_CMD_MUM_IN_GET_VERSION msgrequest */
+#define MC_CMD_MUM_IN_GET_VERSION_LEN 4
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+
+/* MC_CMD_MUM_IN_READ msgrequest */
+#define MC_CMD_MUM_IN_READ_LEN 16
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* ID of (device connected to MUM) to read from registers of */
+#define MC_CMD_MUM_IN_READ_DEVICE_OFST 4
+/* enum: Hittite HMC1035 clock generator on Sorrento board */
+#define MC_CMD_MUM_DEV_HITTITE 0x1
+/* enum: Hittite HMC1035 clock generator for NIC-side on Sorrento board */
+#define MC_CMD_MUM_DEV_HITTITE_NIC 0x2
+/* 32-bit address to read from */
+#define MC_CMD_MUM_IN_READ_ADDR_OFST 8
+/* Number of words to read. */
+#define MC_CMD_MUM_IN_READ_NUMWORDS_OFST 12
+
+/* MC_CMD_MUM_IN_WRITE msgrequest */
+#define MC_CMD_MUM_IN_WRITE_LENMIN 16
+#define MC_CMD_MUM_IN_WRITE_LENMAX 252
+#define MC_CMD_MUM_IN_WRITE_LEN(num) (12+4*(num))
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* ID of (device connected to MUM) to write to registers of */
+#define MC_CMD_MUM_IN_WRITE_DEVICE_OFST 4
+/* enum: Hittite HMC1035 clock generator on Sorrento board */
+/* MC_CMD_MUM_DEV_HITTITE 0x1 */
+/* 32-bit address to write to */
+#define MC_CMD_MUM_IN_WRITE_ADDR_OFST 8
+/* Words to write */
+#define MC_CMD_MUM_IN_WRITE_BUFFER_OFST 12
+#define MC_CMD_MUM_IN_WRITE_BUFFER_LEN 4
+#define MC_CMD_MUM_IN_WRITE_BUFFER_MINNUM 1
+#define MC_CMD_MUM_IN_WRITE_BUFFER_MAXNUM 60
+
+/* MC_CMD_MUM_IN_RAW_CMD msgrequest */
+#define MC_CMD_MUM_IN_RAW_CMD_LENMIN 17
+#define MC_CMD_MUM_IN_RAW_CMD_LENMAX 252
+#define MC_CMD_MUM_IN_RAW_CMD_LEN(num) (16+1*(num))
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* MUM I2C cmd code */
+#define MC_CMD_MUM_IN_RAW_CMD_CMD_CODE_OFST 4
+/* Number of bytes to write */
+#define MC_CMD_MUM_IN_RAW_CMD_NUM_WRITE_OFST 8
+/* Number of bytes to read */
+#define MC_CMD_MUM_IN_RAW_CMD_NUM_READ_OFST 12
+/* Bytes to write */
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_OFST 16
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_LEN 1
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_MINNUM 1
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_MAXNUM 236
+
+/* MC_CMD_MUM_IN_LOG msgrequest */
+#define MC_CMD_MUM_IN_LOG_LEN 8
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_LOG_OP_OFST 4
+#define MC_CMD_MUM_IN_LOG_OP_UART 0x1 /* enum */
+
+/* MC_CMD_MUM_IN_LOG_OP_UART msgrequest */
+#define MC_CMD_MUM_IN_LOG_OP_UART_LEN 12
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* MC_CMD_MUM_IN_LOG_OP_OFST 4 */
+/* Enable/disable debug output to UART */
+#define MC_CMD_MUM_IN_LOG_OP_UART_ENABLE_OFST 8
+
+/* MC_CMD_MUM_IN_GPIO msgrequest */
+#define MC_CMD_MUM_IN_GPIO_LEN 8
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OPCODE_LBN 0
+#define MC_CMD_MUM_IN_GPIO_OPCODE_WIDTH 8
+#define MC_CMD_MUM_IN_GPIO_IN_READ 0x0 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE 0x1 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OUT_READ 0x2 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE 0x3 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ 0x4 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP 0x5 /* enum */
+
+/* MC_CMD_MUM_IN_GPIO_IN_READ msgrequest */
+#define MC_CMD_MUM_IN_GPIO_IN_READ_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_IN_READ_HDR_OFST 4
+
+/* MC_CMD_MUM_IN_GPIO_OUT_WRITE msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_LEN 16
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_HDR_OFST 4
+/* The first 32-bit word to be written to the GPIO OUT register. */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_GPIOMASK1_OFST 8
+/* The second 32-bit word to be written to the GPIO OUT register. */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_GPIOMASK2_OFST 12
+
+/* MC_CMD_MUM_IN_GPIO_OUT_READ msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OUT_READ_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OUT_READ_HDR_OFST 4
+
+/* MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_LEN 16
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_HDR_OFST 4
+/* The first 32-bit word to be written to the GPIO OUT ENABLE register. */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_GPIOMASK1_OFST 8
+/* The second 32-bit word to be written to the GPIO OUT ENABLE register. */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_GPIOMASK2_OFST 12
+
+/* MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ_HDR_OFST 4
+
+/* MC_CMD_MUM_IN_GPIO_OP msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_LBN 8
+#define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_WIDTH 8
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_READ 0x0 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE 0x1 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG 0x2 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE 0x3 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_GPIO_NUMBER_LBN 16
+#define MC_CMD_MUM_IN_GPIO_OP_GPIO_NUMBER_WIDTH 8
+
+/* MC_CMD_MUM_IN_GPIO_OP_OUT_READ msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_READ_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_READ_HDR_OFST 4
+
+/* MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_LBN 24
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_WIDTH 8
+
+/* MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_LBN 24
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_WIDTH 8
+
+/* MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_LBN 24
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_WIDTH 8
+
+/* MC_CMD_MUM_IN_READ_SENSORS msgrequest */
+#define MC_CMD_MUM_IN_READ_SENSORS_LEN 8
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_READ_SENSORS_PARAMS_OFST 4
+#define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_LBN 0
+#define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_WIDTH 8
+#define MC_CMD_MUM_IN_READ_SENSORS_NUM_SENSORS_LBN 8
+#define MC_CMD_MUM_IN_READ_SENSORS_NUM_SENSORS_WIDTH 8
+
+/* MC_CMD_MUM_IN_PROGRAM_CLOCKS msgrequest */
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_LEN 12
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* Bit-mask of clocks to be programmed */
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_MASK_OFST 4
+#define MC_CMD_MUM_CLOCK_ID_FPGA 0x0 /* enum */
+#define MC_CMD_MUM_CLOCK_ID_DDR 0x1 /* enum */
+#define MC_CMD_MUM_CLOCK_ID_NIC 0x2 /* enum */
+/* Control flags for clock programming */
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_FLAGS_OFST 8
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_LBN 0
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_WIDTH 1
+
+/* MC_CMD_MUM_IN_FPGA_LOAD msgrequest */
+#define MC_CMD_MUM_IN_FPGA_LOAD_LEN 8
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* Enable/Disable FPGA config from flash */
+#define MC_CMD_MUM_IN_FPGA_LOAD_ENABLE_OFST 4
+
+/* MC_CMD_MUM_IN_READ_ATB_SENSOR msgrequest */
+#define MC_CMD_MUM_IN_READ_ATB_SENSOR_LEN 4
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+
+/* MC_CMD_MUM_IN_QSFP msgrequest */
+#define MC_CMD_MUM_IN_QSFP_LEN 12
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_OPCODE_LBN 0
+#define MC_CMD_MUM_IN_QSFP_OPCODE_WIDTH 4
+#define MC_CMD_MUM_IN_QSFP_INIT 0x0 /* enum */
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE 0x1 /* enum */
+#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP 0x2 /* enum */
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO 0x3 /* enum */
+#define MC_CMD_MUM_IN_QSFP_FILL_STATS 0x4 /* enum */
+#define MC_CMD_MUM_IN_QSFP_POLL_BIST 0x5 /* enum */
+#define MC_CMD_MUM_IN_QSFP_IDX_OFST 8
+
+/* MC_CMD_MUM_IN_QSFP_INIT msgrequest */
+#define MC_CMD_MUM_IN_QSFP_INIT_LEN 16
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_INIT_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_INIT_IDX_OFST 8
+#define MC_CMD_MUM_IN_QSFP_INIT_CAGE_OFST 12
+
+/* MC_CMD_MUM_IN_QSFP_RECONFIGURE msgrequest */
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_LEN 24
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_IDX_OFST 8
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_TX_DISABLE_OFST 12
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_PORT_LANES_OFST 16
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_PORT_LINK_SPEED_OFST 20
+
+/* MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP msgrequest */
+#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_LEN 12
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_IDX_OFST 8
+
+/* MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO msgrequest */
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_LEN 16
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_IDX_OFST 8
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_PAGE_OFST 12
+
+/* MC_CMD_MUM_IN_QSFP_FILL_STATS msgrequest */
+#define MC_CMD_MUM_IN_QSFP_FILL_STATS_LEN 12
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_FILL_STATS_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_FILL_STATS_IDX_OFST 8
+
+/* MC_CMD_MUM_IN_QSFP_POLL_BIST msgrequest */
+#define MC_CMD_MUM_IN_QSFP_POLL_BIST_LEN 12
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_POLL_BIST_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_POLL_BIST_IDX_OFST 8
+
+/* MC_CMD_MUM_OUT msgresponse */
+#define MC_CMD_MUM_OUT_LEN 0
+
+/* MC_CMD_MUM_OUT_NULL msgresponse */
+#define MC_CMD_MUM_OUT_NULL_LEN 0
+
+/* MC_CMD_MUM_OUT_GET_VERSION msgresponse */
+#define MC_CMD_MUM_OUT_GET_VERSION_LEN 12
+#define MC_CMD_MUM_OUT_GET_VERSION_FIRMWARE_OFST 0
+#define MC_CMD_MUM_OUT_GET_VERSION_VERSION_OFST 4
+#define MC_CMD_MUM_OUT_GET_VERSION_VERSION_LEN 8
+#define MC_CMD_MUM_OUT_GET_VERSION_VERSION_LO_OFST 4
+#define MC_CMD_MUM_OUT_GET_VERSION_VERSION_HI_OFST 8
+
+/* MC_CMD_MUM_OUT_RAW_CMD msgresponse */
+#define MC_CMD_MUM_OUT_RAW_CMD_LENMIN 1
+#define MC_CMD_MUM_OUT_RAW_CMD_LENMAX 252
+#define MC_CMD_MUM_OUT_RAW_CMD_LEN(num) (0+1*(num))
+/* returned data */
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_OFST 0
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_LEN 1
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_MINNUM 1
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_MAXNUM 252
+
+/* MC_CMD_MUM_OUT_READ msgresponse */
+#define MC_CMD_MUM_OUT_READ_LENMIN 4
+#define MC_CMD_MUM_OUT_READ_LENMAX 252
+#define MC_CMD_MUM_OUT_READ_LEN(num) (0+4*(num))
+#define MC_CMD_MUM_OUT_READ_BUFFER_OFST 0
+#define MC_CMD_MUM_OUT_READ_BUFFER_LEN 4
+#define MC_CMD_MUM_OUT_READ_BUFFER_MINNUM 1
+#define MC_CMD_MUM_OUT_READ_BUFFER_MAXNUM 63
+
+/* MC_CMD_MUM_OUT_WRITE msgresponse */
+#define MC_CMD_MUM_OUT_WRITE_LEN 0
+
+/* MC_CMD_MUM_OUT_LOG msgresponse */
+#define MC_CMD_MUM_OUT_LOG_LEN 0
+
+/* MC_CMD_MUM_OUT_LOG_OP_UART msgresponse */
+#define MC_CMD_MUM_OUT_LOG_OP_UART_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_IN_READ msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_IN_READ_LEN 8
+/* The first 32-bit word read from the GPIO IN register. */
+#define MC_CMD_MUM_OUT_GPIO_IN_READ_GPIOMASK1_OFST 0
+/* The second 32-bit word read from the GPIO IN register. */
+#define MC_CMD_MUM_OUT_GPIO_IN_READ_GPIOMASK2_OFST 4
+
+/* MC_CMD_MUM_OUT_GPIO_OUT_WRITE msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OUT_WRITE_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_OUT_READ msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OUT_READ_LEN 8
+/* The first 32-bit word read from the GPIO OUT register. */
+#define MC_CMD_MUM_OUT_GPIO_OUT_READ_GPIOMASK1_OFST 0
+/* The second 32-bit word read from the GPIO OUT register. */
+#define MC_CMD_MUM_OUT_GPIO_OUT_READ_GPIOMASK2_OFST 4
+
+/* MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_WRITE msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_WRITE_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_LEN 8
+#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_GPIOMASK1_OFST 0
+#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_GPIOMASK2_OFST 4
+
+/* MC_CMD_MUM_OUT_GPIO_OP_OUT_READ msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_READ_LEN 4
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_READ_BIT_READ_OFST 0
+
+/* MC_CMD_MUM_OUT_GPIO_OP_OUT_WRITE msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_WRITE_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_OP_OUT_CONFIG msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_CONFIG_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_OP_OUT_ENABLE msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_ENABLE_LEN 0
+
+/* MC_CMD_MUM_OUT_READ_SENSORS msgresponse */
+#define MC_CMD_MUM_OUT_READ_SENSORS_LENMIN 4
+#define MC_CMD_MUM_OUT_READ_SENSORS_LENMAX 252
+#define MC_CMD_MUM_OUT_READ_SENSORS_LEN(num) (0+4*(num))
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_OFST 0
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_LEN 4
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_MINNUM 1
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_MAXNUM 63
+#define MC_CMD_MUM_OUT_READ_SENSORS_READING_LBN 0
+#define MC_CMD_MUM_OUT_READ_SENSORS_READING_WIDTH 16
+#define MC_CMD_MUM_OUT_READ_SENSORS_STATE_LBN 16
+#define MC_CMD_MUM_OUT_READ_SENSORS_STATE_WIDTH 8
+#define MC_CMD_MUM_OUT_READ_SENSORS_TYPE_LBN 24
+#define MC_CMD_MUM_OUT_READ_SENSORS_TYPE_WIDTH 8
+
+/* MC_CMD_MUM_OUT_PROGRAM_CLOCKS msgresponse */
+#define MC_CMD_MUM_OUT_PROGRAM_CLOCKS_LEN 4
+#define MC_CMD_MUM_OUT_PROGRAM_CLOCKS_OK_MASK_OFST 0
+
+/* MC_CMD_MUM_OUT_FPGA_LOAD msgresponse */
+#define MC_CMD_MUM_OUT_FPGA_LOAD_LEN 0
+
+/* MC_CMD_MUM_OUT_READ_ATB_SENSOR msgresponse */
+#define MC_CMD_MUM_OUT_READ_ATB_SENSOR_LEN 4
+#define MC_CMD_MUM_OUT_READ_ATB_SENSOR_RESULT_OFST 0
+
+/* MC_CMD_MUM_OUT_QSFP_INIT msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_INIT_LEN 0
+
+/* MC_CMD_MUM_OUT_QSFP_RECONFIGURE msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_LEN 8
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LP_CAP_OFST 0
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_FLAGS_OFST 4
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_LBN 0
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_WIDTH 1
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LINK_UP_LBN 1
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LINK_UP_WIDTH 1
+
+/* MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP_LEN 4
+#define MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP_PORT_PHY_LP_CAP_OFST 0
+
+/* MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LENMIN 5
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LENMAX 252
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LEN(num) (4+1*(num))
+/* in bytes */
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATALEN_OFST 0
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_OFST 4
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_LEN 1
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_MINNUM 1
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_MAXNUM 248
+
+/* MC_CMD_MUM_OUT_QSFP_FILL_STATS msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_LEN 8
+#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_PORT_PHY_STATS_PMA_PMD_LINK_UP_OFST 0
+#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_PORT_PHY_STATS_PCS_LINK_UP_OFST 4
+
+/* MC_CMD_MUM_OUT_QSFP_POLL_BIST msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_POLL_BIST_LEN 4
+#define MC_CMD_MUM_OUT_QSFP_POLL_BIST_TEST_OFST 0
+
/* MC_CMD_RESOURCE_SPECIFIER enum */
-#define MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff /* enum */
-#define MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe /* enum */
+/* enum: Any */
+#define MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff
+/* enum: None */
+#define MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe
+
+/* EVB_PORT_ID structuredef */
+#define EVB_PORT_ID_LEN 4
+#define EVB_PORT_ID_PORT_ID_OFST 0
+/* enum: An invalid port handle. */
+#define EVB_PORT_ID_NULL 0x0
+/* enum: The port assigned to this function.. */
+#define EVB_PORT_ID_ASSIGNED 0x1000000
+/* enum: External network port 0 */
+#define EVB_PORT_ID_MAC0 0x2000000
+/* enum: External network port 1 */
+#define EVB_PORT_ID_MAC1 0x2000001
+/* enum: External network port 2 */
+#define EVB_PORT_ID_MAC2 0x2000002
+/* enum: External network port 3 */
+#define EVB_PORT_ID_MAC3 0x2000003
+#define EVB_PORT_ID_PORT_ID_LBN 0
+#define EVB_PORT_ID_PORT_ID_WIDTH 32
+
+/* EVB_VLAN_TAG structuredef */
+#define EVB_VLAN_TAG_LEN 2
+/* The VLAN tag value */
+#define EVB_VLAN_TAG_VLAN_ID_LBN 0
+#define EVB_VLAN_TAG_VLAN_ID_WIDTH 12
+#define EVB_VLAN_TAG_MODE_LBN 12
+#define EVB_VLAN_TAG_MODE_WIDTH 4
+/* enum: Insert the VLAN. */
+#define EVB_VLAN_TAG_INSERT 0x0
+/* enum: Replace the VLAN if already present. */
+#define EVB_VLAN_TAG_REPLACE 0x1
+
+/* BUFTBL_ENTRY structuredef */
+#define BUFTBL_ENTRY_LEN 12
+/* the owner ID */
+#define BUFTBL_ENTRY_OID_OFST 0
+#define BUFTBL_ENTRY_OID_LEN 2
+#define BUFTBL_ENTRY_OID_LBN 0
+#define BUFTBL_ENTRY_OID_WIDTH 16
+/* the page parameter as one of ESE_DZ_SMC_PAGE_SIZE_ */
+#define BUFTBL_ENTRY_PGSZ_OFST 2
+#define BUFTBL_ENTRY_PGSZ_LEN 2
+#define BUFTBL_ENTRY_PGSZ_LBN 16
+#define BUFTBL_ENTRY_PGSZ_WIDTH 16
+/* the raw 64-bit address field from the SMC, not adjusted for page size */
+#define BUFTBL_ENTRY_RAWADDR_OFST 4
+#define BUFTBL_ENTRY_RAWADDR_LEN 8
+#define BUFTBL_ENTRY_RAWADDR_LO_OFST 4
+#define BUFTBL_ENTRY_RAWADDR_HI_OFST 8
+#define BUFTBL_ENTRY_RAWADDR_LBN 32
+#define BUFTBL_ENTRY_RAWADDR_WIDTH 64
+
+/* NVRAM_PARTITION_TYPE structuredef */
+#define NVRAM_PARTITION_TYPE_LEN 2
+#define NVRAM_PARTITION_TYPE_ID_OFST 0
+#define NVRAM_PARTITION_TYPE_ID_LEN 2
+/* enum: Primary MC firmware partition */
+#define NVRAM_PARTITION_TYPE_MC_FIRMWARE 0x100
+/* enum: Secondary MC firmware partition */
+#define NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP 0x200
+/* enum: Expansion ROM partition */
+#define NVRAM_PARTITION_TYPE_EXPANSION_ROM 0x300
+/* enum: Static configuration TLV partition */
+#define NVRAM_PARTITION_TYPE_STATIC_CONFIG 0x400
+/* enum: Dynamic configuration TLV partition */
+#define NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG 0x500
+/* enum: Expansion ROM configuration data for port 0 */
+#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT0 0x600
+/* enum: Expansion ROM configuration data for port 1 */
+#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1 0x601
+/* enum: Expansion ROM configuration data for port 2 */
+#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2 0x602
+/* enum: Expansion ROM configuration data for port 3 */
+#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3 0x603
+/* enum: Non-volatile log output partition */
+#define NVRAM_PARTITION_TYPE_LOG 0x700
+/* enum: Device state dump output partition */
+#define NVRAM_PARTITION_TYPE_DUMP 0x800
+/* enum: Application license key storage partition */
+#define NVRAM_PARTITION_TYPE_LICENSE 0x900
+/* enum: Start of range used for PHY partitions (low 8 bits are the PHY ID) */
+#define NVRAM_PARTITION_TYPE_PHY_MIN 0xa00
+/* enum: End of range used for PHY partitions (low 8 bits are the PHY ID) */
+#define NVRAM_PARTITION_TYPE_PHY_MAX 0xaff
+/* enum: Primary FPGA partition */
+#define NVRAM_PARTITION_TYPE_FPGA 0xb00
+/* enum: Secondary FPGA partition */
+#define NVRAM_PARTITION_TYPE_FPGA_BACKUP 0xb01
+/* enum: FC firmware partition */
+#define NVRAM_PARTITION_TYPE_FC_FIRMWARE 0xb02
+/* enum: FC License partition */
+#define NVRAM_PARTITION_TYPE_FC_LICENSE 0xb03
+/* enum: Non-volatile log output partition for FC */
+#define NVRAM_PARTITION_TYPE_FC_LOG 0xb04
+/* enum: MUM firmware partition */
+#define NVRAM_PARTITION_TYPE_MUM_FIRMWARE 0xc00
+/* enum: MUM Non-volatile log output partition. */
+#define NVRAM_PARTITION_TYPE_MUM_LOG 0xc01
+/* enum: MUM Application table partition. */
+#define NVRAM_PARTITION_TYPE_MUM_APPTABLE 0xc02
+/* enum: MUM boot rom partition. */
+#define NVRAM_PARTITION_TYPE_MUM_BOOT_ROM 0xc03
+/* enum: MUM production signatures & calibration rom partition. */
+#define NVRAM_PARTITION_TYPE_MUM_PROD_ROM 0xc04
+/* enum: MUM user signatures & calibration rom partition. */
+#define NVRAM_PARTITION_TYPE_MUM_USER_ROM 0xc05
+/* enum: MUM fuses and lockbits partition. */
+#define NVRAM_PARTITION_TYPE_MUM_FUSELOCK 0xc06
+/* enum: Start of reserved value range (firmware may use for any purpose) */
+#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MIN 0xff00
+/* enum: End of reserved value range (firmware may use for any purpose) */
+#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MAX 0xfffd
+/* enum: Recovery partition map (provided if real map is missing or corrupt) */
+#define NVRAM_PARTITION_TYPE_RECOVERY_MAP 0xfffe
+/* enum: Partition map (real map as stored in flash) */
+#define NVRAM_PARTITION_TYPE_PARTITION_MAP 0xffff
+#define NVRAM_PARTITION_TYPE_ID_LBN 0
+#define NVRAM_PARTITION_TYPE_ID_WIDTH 16
+
+/* LICENSED_APP_ID structuredef */
+#define LICENSED_APP_ID_LEN 4
+#define LICENSED_APP_ID_ID_OFST 0
+/* enum: OpenOnload */
+#define LICENSED_APP_ID_ONLOAD 0x1
+/* enum: PTP timestamping */
+#define LICENSED_APP_ID_PTP 0x2
+/* enum: SolarCapture Pro */
+#define LICENSED_APP_ID_SOLARCAPTURE_PRO 0x4
+/* enum: SolarSecure filter engine */
+#define LICENSED_APP_ID_SOLARSECURE 0x8
+/* enum: Performance monitor */
+#define LICENSED_APP_ID_PERF_MONITOR 0x10
+/* enum: SolarCapture Live */
+#define LICENSED_APP_ID_SOLARCAPTURE_LIVE 0x20
+/* enum: Capture SolarSystem */
+#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM 0x40
+/* enum: Network Access Control */
+#define LICENSED_APP_ID_NETWORK_ACCESS_CONTROL 0x80
+#define LICENSED_APP_ID_ID_LBN 0
+#define LICENSED_APP_ID_ID_WIDTH 32
+
+/* TX_TIMESTAMP_EVENT structuredef */
+#define TX_TIMESTAMP_EVENT_LEN 6
+/* lower 16 bits of timestamp data */
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO_OFST 0
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO_LEN 2
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO_LBN 0
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO_WIDTH 16
+/* Type of TX event, ordinary TX completion, low or high part of TX timestamp
+ */
+#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_OFST 3
+#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LEN 1
+/* enum: This is a TX completion event, not a timestamp */
+#define TX_TIMESTAMP_EVENT_TX_EV_COMPLETION 0x0
+/* enum: This is the low part of a TX timestamp event */
+#define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_LO 0x51
+/* enum: This is the high part of a TX timestamp event */
+#define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_HI 0x52
+#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LBN 24
+#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_WIDTH 8
+/* upper 16 bits of timestamp data */
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI_OFST 4
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI_LEN 2
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI_LBN 32
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI_WIDTH 16
+
+/* RSS_MODE structuredef */
+#define RSS_MODE_LEN 1
+/* The RSS mode for a particular packet type is a value from 0 - 15 which can
+ * be considered as 4 bits selecting which fields are included in the hash. (A
+ * value 0 effectively disables RSS spreading for the packet type.) The YAML
+ * generation tools require this structure to be a whole number of bytes wide,
+ * but only 4 bits are relevant.
+ */
+#define RSS_MODE_HASH_SELECTOR_OFST 0
+#define RSS_MODE_HASH_SELECTOR_LEN 1
+#define RSS_MODE_HASH_SRC_ADDR_LBN 0
+#define RSS_MODE_HASH_SRC_ADDR_WIDTH 1
+#define RSS_MODE_HASH_DST_ADDR_LBN 1
+#define RSS_MODE_HASH_DST_ADDR_WIDTH 1
+#define RSS_MODE_HASH_SRC_PORT_LBN 2
+#define RSS_MODE_HASH_SRC_PORT_WIDTH 1
+#define RSS_MODE_HASH_DST_PORT_LBN 3
+#define RSS_MODE_HASH_DST_PORT_WIDTH 1
+#define RSS_MODE_HASH_SELECTOR_LBN 0
+#define RSS_MODE_HASH_SELECTOR_WIDTH 8
/***********************************/
-/* MC_CMD_INIT_EVQ
+/* MC_CMD_READ_REGS
+ * Get a dump of the MCPU registers
*/
-#define MC_CMD_INIT_EVQ 0x50
+#define MC_CMD_READ_REGS 0x50
+#undef MC_CMD_0x50_PRIVILEGE_CTG
+
+#define MC_CMD_0x50_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_READ_REGS_IN msgrequest */
+#define MC_CMD_READ_REGS_IN_LEN 0
+
+/* MC_CMD_READ_REGS_OUT msgresponse */
+#define MC_CMD_READ_REGS_OUT_LEN 308
+/* Whether the corresponding register entry contains a valid value */
+#define MC_CMD_READ_REGS_OUT_MASK_OFST 0
+#define MC_CMD_READ_REGS_OUT_MASK_LEN 16
+/* Same order as MIPS GDB (r0-r31, sr, lo, hi, bad, cause, 32 x float, fsr,
+ * fir, fp)
+ */
+#define MC_CMD_READ_REGS_OUT_REGS_OFST 16
+#define MC_CMD_READ_REGS_OUT_REGS_LEN 4
+#define MC_CMD_READ_REGS_OUT_REGS_NUM 73
+
+
+/***********************************/
+/* MC_CMD_INIT_EVQ
+ * Set up an event queue according to the supplied parameters. The IN arguments
+ * end with an address for each 4k of host memory required to back the EVQ.
+ */
+#define MC_CMD_INIT_EVQ 0x80
+#undef MC_CMD_0x80_PRIVILEGE_CTG
+
+#define MC_CMD_0x80_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_INIT_EVQ_IN msgrequest */
-#define MC_CMD_INIT_EVQ_IN_LENMIN 36
-#define MC_CMD_INIT_EVQ_IN_LENMAX 540
-#define MC_CMD_INIT_EVQ_IN_LEN(num) (28+8*(num))
+#define MC_CMD_INIT_EVQ_IN_LENMIN 44
+#define MC_CMD_INIT_EVQ_IN_LENMAX 548
+#define MC_CMD_INIT_EVQ_IN_LEN(num) (36+8*(num))
+/* Size, in entries */
#define MC_CMD_INIT_EVQ_IN_SIZE_OFST 0
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
#define MC_CMD_INIT_EVQ_IN_INSTANCE_OFST 4
+/* The initial timer value. The load value is ignored if the timer mode is DIS.
+ */
#define MC_CMD_INIT_EVQ_IN_TMR_LOAD_OFST 8
+/* The reload value is ignored in one-shot modes */
#define MC_CMD_INIT_EVQ_IN_TMR_RELOAD_OFST 12
+/* tbd */
#define MC_CMD_INIT_EVQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_LBN 0
#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_WIDTH 1
#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_LBN 1
#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_INT_ARMD_LBN 2
+#define MC_CMD_INIT_EVQ_IN_FLAG_INT_ARMD_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_CUT_THRU_LBN 3
+#define MC_CMD_INIT_EVQ_IN_FLAG_CUT_THRU_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_RX_MERGE_LBN 4
+#define MC_CMD_INIT_EVQ_IN_FLAG_RX_MERGE_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_TX_MERGE_LBN 5
+#define MC_CMD_INIT_EVQ_IN_FLAG_TX_MERGE_WIDTH 1
#define MC_CMD_INIT_EVQ_IN_TMR_MODE_OFST 20
-#define MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS 0x0 /* enum */
-#define MC_CMD_INIT_EVQ_IN_TMR_IMMED_START 0x1 /* enum */
-#define MC_CMD_INIT_EVQ_IN_TMR_TRIG_START 0x2 /* enum */
-#define MC_CMD_INIT_EVQ_IN_TMR_INT_HLDOFF 0x3 /* enum */
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS 0x0
+/* enum: Immediate */
+#define MC_CMD_INIT_EVQ_IN_TMR_IMMED_START 0x1
+/* enum: Triggered */
+#define MC_CMD_INIT_EVQ_IN_TMR_TRIG_START 0x2
+/* enum: Hold-off */
+#define MC_CMD_INIT_EVQ_IN_TMR_INT_HLDOFF 0x3
+/* Target EVQ for wakeups if in wakeup mode. */
#define MC_CMD_INIT_EVQ_IN_TARGET_EVQ_OFST 24
+/* Target interrupt if in interrupting mode (note union with target EVQ). Use
+ * MC_CMD_RESOURCE_INSTANCE_ANY unless a specific one required for test
+ * purposes.
+ */
#define MC_CMD_INIT_EVQ_IN_IRQ_NUM_OFST 24
-#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_OFST 28
+/* Event Counter Mode. */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_OFST 28
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS 0x0
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_RX 0x1
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_TX 0x2
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_RXTX 0x3
+/* Event queue packet count threshold. */
+#define MC_CMD_INIT_EVQ_IN_COUNT_THRSHLD_OFST 32
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_OFST 36
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LEN 8
-#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LO_OFST 28
-#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_HI_OFST 32
+#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LO_OFST 36
+#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_HI_OFST 40
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MAXNUM 64
/* MC_CMD_INIT_EVQ_OUT msgresponse */
#define MC_CMD_INIT_EVQ_OUT_LEN 4
+/* Only valid if INTRFLAG was true */
#define MC_CMD_INIT_EVQ_OUT_IRQ_OFST 0
/* QUEUE_CRC_MODE structuredef */
#define QUEUE_CRC_MODE_LEN 1
#define QUEUE_CRC_MODE_MODE_LBN 0
#define QUEUE_CRC_MODE_MODE_WIDTH 4
-#define QUEUE_CRC_MODE_NONE 0x0 /* enum */
-#define QUEUE_CRC_MODE_FCOE 0x1 /* enum */
-#define QUEUE_CRC_MODE_ISCSI_HDR 0x2 /* enum */
-#define QUEUE_CRC_MODE_ISCSI 0x3 /* enum */
-#define QUEUE_CRC_MODE_FCOIPOE 0x4 /* enum */
-#define QUEUE_CRC_MODE_MPA 0x5 /* enum */
+/* enum: No CRC. */
+#define QUEUE_CRC_MODE_NONE 0x0
+/* enum: CRC Fiber channel over ethernet. */
+#define QUEUE_CRC_MODE_FCOE 0x1
+/* enum: CRC (digest) iSCSI header only. */
+#define QUEUE_CRC_MODE_ISCSI_HDR 0x2
+/* enum: CRC (digest) iSCSI header and payload. */
+#define QUEUE_CRC_MODE_ISCSI 0x3
+/* enum: CRC Fiber channel over IP over ethernet. */
+#define QUEUE_CRC_MODE_FCOIPOE 0x4
+/* enum: CRC MPA. */
+#define QUEUE_CRC_MODE_MPA 0x5
#define QUEUE_CRC_MODE_SPARE_LBN 4
#define QUEUE_CRC_MODE_SPARE_WIDTH 4
/***********************************/
-/* MC_CMD_INIT_RXQ
+/* MC_CMD_INIT_RXQ
+ * set up a receive queue according to the supplied parameters. The IN
+ * arguments end with an address for each 4k of host memory required to back
+ * the RXQ.
*/
-#define MC_CMD_INIT_RXQ 0x51
+#define MC_CMD_INIT_RXQ 0x81
+#undef MC_CMD_0x81_PRIVILEGE_CTG
+
+#define MC_CMD_0x81_PRIVILEGE_CTG SRIOV_CTG_GENERAL
-/* MC_CMD_INIT_RXQ_IN msgrequest */
-#define MC_CMD_INIT_RXQ_IN_LENMIN 32
-#define MC_CMD_INIT_RXQ_IN_LENMAX 248
-#define MC_CMD_INIT_RXQ_IN_LEN(num) (24+8*(num))
+/* MC_CMD_INIT_RXQ_IN msgrequest: Legacy RXQ_INIT request. Use extended version
+ * in new code.
+ */
+#define MC_CMD_INIT_RXQ_IN_LENMIN 36
+#define MC_CMD_INIT_RXQ_IN_LENMAX 252
+#define MC_CMD_INIT_RXQ_IN_LEN(num) (28+8*(num))
+/* Size, in entries */
#define MC_CMD_INIT_RXQ_IN_SIZE_OFST 0
+/* The EVQ to send events to. This is an index originally specified to INIT_EVQ
+ */
#define MC_CMD_INIT_RXQ_IN_TARGET_EVQ_OFST 4
+/* The value to put in the event data. Check hardware spec. for valid range. */
#define MC_CMD_INIT_RXQ_IN_LABEL_OFST 8
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
#define MC_CMD_INIT_RXQ_IN_INSTANCE_OFST 12
+/* There will be more flags here. */
#define MC_CMD_INIT_RXQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_WIDTH 1
#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_LBN 1
#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_WIDTH 1
-#define MC_CMD_INIT_RXQ_IN_FLAG_PKT_EDIT_LBN 2
-#define MC_CMD_INIT_RXQ_IN_FLAG_PKT_EDIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_TIMESTAMP_LBN 2
+#define MC_CMD_INIT_RXQ_IN_FLAG_TIMESTAMP_WIDTH 1
#define MC_CMD_INIT_RXQ_IN_CRC_MODE_LBN 3
#define MC_CMD_INIT_RXQ_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_LBN 7
+#define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_LBN 8
+#define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_LBN 9
+#define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
#define MC_CMD_INIT_RXQ_IN_OWNER_ID_OFST 20
-#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_OFST 24
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_RXQ_IN_PORT_ID_OFST 24
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_OFST 28
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LEN 8
-#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LO_OFST 24
-#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_HI_OFST 28
+#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_HI_OFST 32
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MAXNUM 28
+/* MC_CMD_INIT_RXQ_EXT_IN msgrequest: Extended RXQ_INIT with additional mode
+ * flags
+ */
+#define MC_CMD_INIT_RXQ_EXT_IN_LEN 544
+/* Size, in entries */
+#define MC_CMD_INIT_RXQ_EXT_IN_SIZE_OFST 0
+/* The EVQ to send events to. This is an index originally specified to INIT_EVQ
+ */
+#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_OFST 4
+/* The value to put in the event data. Check hardware spec. for valid range. */
+#define MC_CMD_INIT_RXQ_EXT_IN_LABEL_OFST 8
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
+#define MC_CMD_INIT_RXQ_EXT_IN_INSTANCE_OFST 12
+/* There will be more flags here. */
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAGS_OFST 16
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_LBN 0
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT_LBN 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_TIMESTAMP_LBN 2
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_CRC_MODE_LBN 3
+#define MC_CMD_INIT_RXQ_EXT_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_CHAIN_LBN 7
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_PREFIX_LBN 8
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER_LBN 9
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_LBN 10
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_WIDTH 4
+/* enum: One packet per descriptor (for normal networking) */
+#define MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET 0x0
+/* enum: Pack multiple packets into large descriptors (for SolarCapture) */
+#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM 0x1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_LBN 14
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_LBN 15
+#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M 0x0 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K 0x1 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K 0x2 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K 0x3 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K 0x4 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_LBN 18
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
+#define MC_CMD_INIT_RXQ_EXT_IN_OWNER_ID_OFST 20
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_RXQ_EXT_IN_PORT_ID_OFST 24
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_OFST 28
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_LEN 8
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_HI_OFST 32
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_NUM 64
+/* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */
+#define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_OFST 540
+
/* MC_CMD_INIT_RXQ_OUT msgresponse */
#define MC_CMD_INIT_RXQ_OUT_LEN 0
+/* MC_CMD_INIT_RXQ_EXT_OUT msgresponse */
+#define MC_CMD_INIT_RXQ_EXT_OUT_LEN 0
+
/***********************************/
-/* MC_CMD_INIT_TXQ
+/* MC_CMD_INIT_TXQ
*/
-#define MC_CMD_INIT_TXQ 0x52
+#define MC_CMD_INIT_TXQ 0x82
+#undef MC_CMD_0x82_PRIVILEGE_CTG
+
+#define MC_CMD_0x82_PRIVILEGE_CTG SRIOV_CTG_GENERAL
-/* MC_CMD_INIT_TXQ_IN msgrequest */
-#define MC_CMD_INIT_TXQ_IN_LENMIN 32
-#define MC_CMD_INIT_TXQ_IN_LENMAX 248
-#define MC_CMD_INIT_TXQ_IN_LEN(num) (24+8*(num))
+/* MC_CMD_INIT_TXQ_IN msgrequest: Legacy INIT_TXQ request. Use extended version
+ * in new code.
+ */
+#define MC_CMD_INIT_TXQ_IN_LENMIN 36
+#define MC_CMD_INIT_TXQ_IN_LENMAX 252
+#define MC_CMD_INIT_TXQ_IN_LEN(num) (28+8*(num))
+/* Size, in entries */
#define MC_CMD_INIT_TXQ_IN_SIZE_OFST 0
+/* The EVQ to send events to. This is an index originally specified to
+ * INIT_EVQ.
+ */
#define MC_CMD_INIT_TXQ_IN_TARGET_EVQ_OFST 4
+/* The value to put in the event data. Check hardware spec. for valid range. */
#define MC_CMD_INIT_TXQ_IN_LABEL_OFST 8
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
#define MC_CMD_INIT_TXQ_IN_INSTANCE_OFST 12
+/* There will be more flags here. */
#define MC_CMD_INIT_TXQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_WIDTH 1
@@ -4587,25 +7817,101 @@
#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_UDP_ONLY_WIDTH 1
#define MC_CMD_INIT_TXQ_IN_CRC_MODE_LBN 4
#define MC_CMD_INIT_TXQ_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_TXQ_IN_FLAG_TIMESTAMP_LBN 8
+#define MC_CMD_INIT_TXQ_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_PACER_BYPASS_LBN 9
+#define MC_CMD_INIT_TXQ_IN_FLAG_PACER_BYPASS_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_IP_CSUM_EN_LBN 10
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_IP_CSUM_EN_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_TCP_CSUM_EN_LBN 11
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_TCP_CSUM_EN_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
#define MC_CMD_INIT_TXQ_IN_OWNER_ID_OFST 20
-#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_OFST 24
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_TXQ_IN_PORT_ID_OFST 24
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_OFST 28
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LEN 8
-#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LO_OFST 24
-#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_HI_OFST 28
+#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_HI_OFST 32
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MAXNUM 28
+/* MC_CMD_INIT_TXQ_EXT_IN msgrequest: Extended INIT_TXQ with additional mode
+ * flags
+ */
+#define MC_CMD_INIT_TXQ_EXT_IN_LEN 544
+/* Size, in entries */
+#define MC_CMD_INIT_TXQ_EXT_IN_SIZE_OFST 0
+/* The EVQ to send events to. This is an index originally specified to
+ * INIT_EVQ.
+ */
+#define MC_CMD_INIT_TXQ_EXT_IN_TARGET_EVQ_OFST 4
+/* The value to put in the event data. Check hardware spec. for valid range. */
+#define MC_CMD_INIT_TXQ_EXT_IN_LABEL_OFST 8
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
+#define MC_CMD_INIT_TXQ_EXT_IN_INSTANCE_OFST 12
+/* There will be more flags here. */
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAGS_OFST 16
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_LBN 0
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_IP_CSUM_DIS_LBN 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_IP_CSUM_DIS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_CSUM_DIS_LBN 2
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_CSUM_DIS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_UDP_ONLY_LBN 3
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_UDP_ONLY_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_CRC_MODE_LBN 4
+#define MC_CMD_INIT_TXQ_EXT_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TIMESTAMP_LBN 8
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_PACER_BYPASS_LBN 9
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_PACER_BYPASS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_IP_CSUM_EN_LBN 10
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_IP_CSUM_EN_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_TCP_CSUM_EN_LBN 11
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_TCP_CSUM_EN_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
+#define MC_CMD_INIT_TXQ_EXT_IN_OWNER_ID_OFST 20
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_TXQ_EXT_IN_PORT_ID_OFST 24
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_OFST 28
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_LEN 8
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_HI_OFST 32
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MINNUM 1
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MAXNUM 64
+/* Flags related to Qbb flow control mode. */
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_FLAGS_OFST 540
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_LBN 0
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_PRIORITY_LBN 1
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_PRIORITY_WIDTH 3
+
/* MC_CMD_INIT_TXQ_OUT msgresponse */
#define MC_CMD_INIT_TXQ_OUT_LEN 0
/***********************************/
-/* MC_CMD_FINI_EVQ
+/* MC_CMD_FINI_EVQ
+ * Teardown an EVQ.
+ *
+ * All DMAQs or EVQs that point to the EVQ to tear down must be torn down first
+ * or the operation will fail with EBUSY
*/
-#define MC_CMD_FINI_EVQ 0x55
+#define MC_CMD_FINI_EVQ 0x83
+#undef MC_CMD_0x83_PRIVILEGE_CTG
+
+#define MC_CMD_0x83_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FINI_EVQ_IN msgrequest */
#define MC_CMD_FINI_EVQ_IN_LEN 4
+/* Instance of EVQ to destroy. Should be the same instance as that previously
+ * passed to INIT_EVQ
+ */
#define MC_CMD_FINI_EVQ_IN_INSTANCE_OFST 0
/* MC_CMD_FINI_EVQ_OUT msgresponse */
@@ -4613,12 +7919,17 @@
/***********************************/
-/* MC_CMD_FINI_RXQ
+/* MC_CMD_FINI_RXQ
+ * Teardown a RXQ.
*/
-#define MC_CMD_FINI_RXQ 0x56
+#define MC_CMD_FINI_RXQ 0x84
+#undef MC_CMD_0x84_PRIVILEGE_CTG
+
+#define MC_CMD_0x84_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FINI_RXQ_IN msgrequest */
#define MC_CMD_FINI_RXQ_IN_LEN 4
+/* Instance of RXQ to destroy */
#define MC_CMD_FINI_RXQ_IN_INSTANCE_OFST 0
/* MC_CMD_FINI_RXQ_OUT msgresponse */
@@ -4626,12 +7937,17 @@
/***********************************/
-/* MC_CMD_FINI_TXQ
+/* MC_CMD_FINI_TXQ
+ * Teardown a TXQ.
*/
-#define MC_CMD_FINI_TXQ 0x57
+#define MC_CMD_FINI_TXQ 0x85
+#undef MC_CMD_0x85_PRIVILEGE_CTG
+
+#define MC_CMD_0x85_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FINI_TXQ_IN msgrequest */
#define MC_CMD_FINI_TXQ_IN_LEN 4
+/* Instance of TXQ to destroy */
#define MC_CMD_FINI_TXQ_IN_INSTANCE_OFST 0
/* MC_CMD_FINI_TXQ_OUT msgresponse */
@@ -4639,102 +7955,247 @@
/***********************************/
-/* MC_CMD_DRIVER_EVENT
+/* MC_CMD_DRIVER_EVENT
+ * Generate an event on an EVQ belonging to the function issuing the command.
*/
-#define MC_CMD_DRIVER_EVENT 0x5a
+#define MC_CMD_DRIVER_EVENT 0x86
+#undef MC_CMD_0x86_PRIVILEGE_CTG
+
+#define MC_CMD_0x86_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_DRIVER_EVENT_IN msgrequest */
#define MC_CMD_DRIVER_EVENT_IN_LEN 12
+/* Handle of target EVQ */
#define MC_CMD_DRIVER_EVENT_IN_EVQ_OFST 0
+/* Bits 0 - 63 of event */
#define MC_CMD_DRIVER_EVENT_IN_DATA_OFST 4
#define MC_CMD_DRIVER_EVENT_IN_DATA_LEN 8
#define MC_CMD_DRIVER_EVENT_IN_DATA_LO_OFST 4
#define MC_CMD_DRIVER_EVENT_IN_DATA_HI_OFST 8
+/* MC_CMD_DRIVER_EVENT_OUT msgresponse */
+#define MC_CMD_DRIVER_EVENT_OUT_LEN 0
+
/***********************************/
-/* MC_CMD_PROXY_CMD
+/* MC_CMD_PROXY_CMD
+ * Execute an arbitrary MCDI command on behalf of a different function, subject
+ * to security restrictions. The command to be proxied follows immediately
+ * afterward in the host buffer (or on the UART). This command supercedes
+ * MC_CMD_SET_FUNC, which remains available for Siena but now deprecated.
*/
-#define MC_CMD_PROXY_CMD 0x5b
+#define MC_CMD_PROXY_CMD 0x5b
+#undef MC_CMD_0x5b_PRIVILEGE_CTG
+
+#define MC_CMD_0x5b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_PROXY_CMD_IN msgrequest */
#define MC_CMD_PROXY_CMD_IN_LEN 4
+/* The handle of the target function. */
#define MC_CMD_PROXY_CMD_IN_TARGET_OFST 0
+#define MC_CMD_PROXY_CMD_IN_TARGET_PF_LBN 0
+#define MC_CMD_PROXY_CMD_IN_TARGET_PF_WIDTH 16
+#define MC_CMD_PROXY_CMD_IN_TARGET_VF_LBN 16
+#define MC_CMD_PROXY_CMD_IN_TARGET_VF_WIDTH 16
+#define MC_CMD_PROXY_CMD_IN_VF_NULL 0xffff /* enum */
+/* MC_CMD_PROXY_CMD_OUT msgresponse */
+#define MC_CMD_PROXY_CMD_OUT_LEN 0
-/***********************************/
-/* MC_CMD_ALLOC_OWNER_IDS
+/* MC_PROXY_STATUS_BUFFER structuredef: Host memory status buffer used to
+ * manage proxied requests
*/
-#define MC_CMD_ALLOC_OWNER_IDS 0x54
+#define MC_PROXY_STATUS_BUFFER_LEN 16
+/* Handle allocated by the firmware for this proxy transaction */
+#define MC_PROXY_STATUS_BUFFER_HANDLE_OFST 0
+/* enum: An invalid handle. */
+#define MC_PROXY_STATUS_BUFFER_HANDLE_INVALID 0x0
+#define MC_PROXY_STATUS_BUFFER_HANDLE_LBN 0
+#define MC_PROXY_STATUS_BUFFER_HANDLE_WIDTH 32
+/* The requesting physical function number */
+#define MC_PROXY_STATUS_BUFFER_PF_OFST 4
+#define MC_PROXY_STATUS_BUFFER_PF_LEN 2
+#define MC_PROXY_STATUS_BUFFER_PF_LBN 32
+#define MC_PROXY_STATUS_BUFFER_PF_WIDTH 16
+/* The requesting virtual function number. Set to VF_NULL if the target is a
+ * PF.
+ */
+#define MC_PROXY_STATUS_BUFFER_VF_OFST 6
+#define MC_PROXY_STATUS_BUFFER_VF_LEN 2
+#define MC_PROXY_STATUS_BUFFER_VF_LBN 48
+#define MC_PROXY_STATUS_BUFFER_VF_WIDTH 16
+/* The target function RID. */
+#define MC_PROXY_STATUS_BUFFER_RID_OFST 8
+#define MC_PROXY_STATUS_BUFFER_RID_LEN 2
+#define MC_PROXY_STATUS_BUFFER_RID_LBN 64
+#define MC_PROXY_STATUS_BUFFER_RID_WIDTH 16
+/* The status of the proxy as described in MC_CMD_PROXY_COMPLETE. */
+#define MC_PROXY_STATUS_BUFFER_STATUS_OFST 10
+#define MC_PROXY_STATUS_BUFFER_STATUS_LEN 2
+#define MC_PROXY_STATUS_BUFFER_STATUS_LBN 80
+#define MC_PROXY_STATUS_BUFFER_STATUS_WIDTH 16
+/* If a request is authorized rather than carried out by the host, this is the
+ * elevated privilege mask granted to the requesting function.
+ */
+#define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_OFST 12
+#define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_LBN 96
+#define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_WIDTH 32
-/* MC_CMD_ALLOC_OWNER_IDS_IN msgrequest */
-#define MC_CMD_ALLOC_OWNER_IDS_IN_LEN 4
-#define MC_CMD_ALLOC_OWNER_IDS_IN_NIDS_OFST 0
-/* MC_CMD_ALLOC_OWNER_IDS_OUT msgresponse */
-#define MC_CMD_ALLOC_OWNER_IDS_OUT_LEN 12
-#define MC_CMD_ALLOC_OWNER_IDS_OUT_HANDLE_OFST 0
-#define MC_CMD_ALLOC_OWNER_IDS_OUT_NIDS_OFST 4
-#define MC_CMD_ALLOC_OWNER_IDS_OUT_BASE_OFST 8
+/***********************************/
+/* MC_CMD_PROXY_CONFIGURE
+ * Enable/disable authorization of MCDI requests from unprivileged functions by
+ * a designated admin function
+ */
+#define MC_CMD_PROXY_CONFIGURE 0x58
+#undef MC_CMD_0x58_PRIVILEGE_CTG
+
+#define MC_CMD_0x58_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_PROXY_CONFIGURE_IN msgrequest */
+#define MC_CMD_PROXY_CONFIGURE_IN_LEN 108
+#define MC_CMD_PROXY_CONFIGURE_IN_FLAGS_OFST 0
+#define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_LBN 0
+#define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_WIDTH 1
+/* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS
+ * of blocks, each of the size REQUEST_BLOCK_SIZE.
+ */
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_OFST 4
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_LEN 8
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_LO_OFST 4
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_HI_OFST 8
+/* Must be a power of 2 */
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BLOCK_SIZE_OFST 12
+/* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS
+ * of blocks, each of the size REPLY_BLOCK_SIZE.
+ */
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_OFST 16
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_LEN 8
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_LO_OFST 16
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_HI_OFST 20
+/* Must be a power of 2 */
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BLOCK_SIZE_OFST 24
+/* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS
+ * of blocks, each of the size STATUS_BLOCK_SIZE. This buffer is only needed if
+ * host intends to complete proxied operations by using MC_CMD_PROXY_CMD.
+ */
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_OFST 28
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_LEN 8
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_LO_OFST 28
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_HI_OFST 32
+/* Must be a power of 2, or zero if this buffer is not provided */
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BLOCK_SIZE_OFST 36
+/* Applies to all three buffers */
+#define MC_CMD_PROXY_CONFIGURE_IN_NUM_BLOCKS_OFST 40
+/* A bit mask defining which MCDI operations may be proxied */
+#define MC_CMD_PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK_OFST 44
+#define MC_CMD_PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK_LEN 64
+
+/* MC_CMD_PROXY_CONFIGURE_OUT msgresponse */
+#define MC_CMD_PROXY_CONFIGURE_OUT_LEN 0
/***********************************/
-/* MC_CMD_FREE_OWNER_IDS
+/* MC_CMD_PROXY_COMPLETE
+ * Tells FW that a requested proxy operation has either been completed (by
+ * using MC_CMD_PROXY_CMD) or authorized/declined. May only be sent by the
+ * function that enabled proxying/authorization (by using
+ * MC_CMD_PROXY_CONFIGURE).
*/
-#define MC_CMD_FREE_OWNER_IDS 0x59
+#define MC_CMD_PROXY_COMPLETE 0x5f
+#undef MC_CMD_0x5f_PRIVILEGE_CTG
+
+#define MC_CMD_0x5f_PRIVILEGE_CTG SRIOV_CTG_ADMIN
-/* MC_CMD_FREE_OWNER_IDS_IN msgrequest */
-#define MC_CMD_FREE_OWNER_IDS_IN_LEN 4
-#define MC_CMD_FREE_OWNER_IDS_IN_HANDLE_OFST 0
+/* MC_CMD_PROXY_COMPLETE_IN msgrequest */
+#define MC_CMD_PROXY_COMPLETE_IN_LEN 12
+#define MC_CMD_PROXY_COMPLETE_IN_BLOCK_INDEX_OFST 0
+#define MC_CMD_PROXY_COMPLETE_IN_STATUS_OFST 4
+/* enum: The operation has been completed by using MC_CMD_PROXY_CMD, the reply
+ * is stored in the REPLY_BUFF.
+ */
+#define MC_CMD_PROXY_COMPLETE_IN_COMPLETE 0x0
+/* enum: The operation has been authorized. The originating function may now
+ * try again.
+ */
+#define MC_CMD_PROXY_COMPLETE_IN_AUTHORIZED 0x1
+/* enum: The operation has been declined. */
+#define MC_CMD_PROXY_COMPLETE_IN_DECLINED 0x2
+/* enum: The authorization failed because the relevant application did not
+ * respond in time.
+ */
+#define MC_CMD_PROXY_COMPLETE_IN_TIMEDOUT 0x3
+#define MC_CMD_PROXY_COMPLETE_IN_HANDLE_OFST 8
-/* MC_CMD_FREE_OWNER_IDS_OUT msgresponse */
-#define MC_CMD_FREE_OWNER_IDS_OUT_LEN 0
+/* MC_CMD_PROXY_COMPLETE_OUT msgresponse */
+#define MC_CMD_PROXY_COMPLETE_OUT_LEN 0
/***********************************/
-/* MC_CMD_ALLOC_BUFTBL_CHUNK
+/* MC_CMD_ALLOC_BUFTBL_CHUNK
+ * Allocate a set of buffer table entries using the specified owner ID. This
+ * operation allocates the required buffer table entries (and fails if it
+ * cannot do so). The buffer table entries will initially be zeroed.
*/
-#define MC_CMD_ALLOC_BUFTBL_CHUNK 0x5c
+#define MC_CMD_ALLOC_BUFTBL_CHUNK 0x87
+#undef MC_CMD_0x87_PRIVILEGE_CTG
+
+#define MC_CMD_0x87_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_ALLOC_BUFTBL_CHUNK_IN msgrequest */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_LEN 8
+/* Owner ID to use */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_OWNER_OFST 0
+/* Size of buffer table pages to use, in bytes (note that only a few values are
+ * legal on any specific hardware).
+ */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_PAGE_SIZE_OFST 4
/* MC_CMD_ALLOC_BUFTBL_CHUNK_OUT msgresponse */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_LEN 12
#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_HANDLE_OFST 0
#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_NUMENTRIES_OFST 4
+/* Buffer table IDs for use in DMA descriptors. */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_ID_OFST 8
/***********************************/
-/* MC_CMD_PROGRAM_BUFTBL_ENTRIES
+/* MC_CMD_PROGRAM_BUFTBL_ENTRIES
+ * Reprogram a set of buffer table entries in the specified chunk.
*/
-#define MC_CMD_PROGRAM_BUFTBL_ENTRIES 0x5d
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES 0x88
+#undef MC_CMD_0x88_PRIVILEGE_CTG
+
+#define MC_CMD_0x88_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN msgrequest */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMIN 20
-#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 252
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 268
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LEN(num) (12+8*(num))
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_OFST 0
+/* ID */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_FIRSTID_OFST 4
+/* Num entries */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_NUMENTRIES_OFST 8
+/* Buffer table entry address */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_OFST 12
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LEN 8
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LO_OFST 12
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_HI_OFST 16
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MINNUM 1
-#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM 30
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM 32
/* MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT msgresponse */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT_LEN 0
/***********************************/
-/* MC_CMD_FREE_BUFTBL_CHUNK
+/* MC_CMD_FREE_BUFTBL_CHUNK
*/
-#define MC_CMD_FREE_BUFTBL_CHUNK 0x5e
+#define MC_CMD_FREE_BUFTBL_CHUNK 0x89
+#undef MC_CMD_0x89_PRIVILEGE_CTG
+
+#define MC_CMD_0x89_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_FREE_BUFTBL_CHUNK_IN msgrequest */
#define MC_CMD_FREE_BUFTBL_CHUNK_IN_LEN 4
@@ -4743,35 +8204,80 @@
/* MC_CMD_FREE_BUFTBL_CHUNK_OUT msgresponse */
#define MC_CMD_FREE_BUFTBL_CHUNK_OUT_LEN 0
-
-/***********************************/
-/* MC_CMD_GET_PF_COUNT
- */
-#define MC_CMD_GET_PF_COUNT 0x60
-
-/* MC_CMD_GET_PF_COUNT_IN msgrequest */
-#define MC_CMD_GET_PF_COUNT_IN_LEN 0
-
-/* MC_CMD_GET_PF_COUNT_OUT msgresponse */
-#define MC_CMD_GET_PF_COUNT_OUT_LEN 1
-#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST 0
-#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_LEN 1
+/* PORT_CONFIG_ENTRY structuredef */
+#define PORT_CONFIG_ENTRY_LEN 16
+/* External port number (label) */
+#define PORT_CONFIG_ENTRY_EXT_NUMBER_OFST 0
+#define PORT_CONFIG_ENTRY_EXT_NUMBER_LEN 1
+#define PORT_CONFIG_ENTRY_EXT_NUMBER_LBN 0
+#define PORT_CONFIG_ENTRY_EXT_NUMBER_WIDTH 8
+/* Port core location */
+#define PORT_CONFIG_ENTRY_CORE_OFST 1
+#define PORT_CONFIG_ENTRY_CORE_LEN 1
+#define PORT_CONFIG_ENTRY_STANDALONE 0x0 /* enum */
+#define PORT_CONFIG_ENTRY_MASTER 0x1 /* enum */
+#define PORT_CONFIG_ENTRY_SLAVE 0x2 /* enum */
+#define PORT_CONFIG_ENTRY_CORE_LBN 8
+#define PORT_CONFIG_ENTRY_CORE_WIDTH 8
+/* Internal number (HW resource) relative to the core */
+#define PORT_CONFIG_ENTRY_INT_NUMBER_OFST 2
+#define PORT_CONFIG_ENTRY_INT_NUMBER_LEN 1
+#define PORT_CONFIG_ENTRY_INT_NUMBER_LBN 16
+#define PORT_CONFIG_ENTRY_INT_NUMBER_WIDTH 8
+/* Reserved */
+#define PORT_CONFIG_ENTRY_RSVD_OFST 3
+#define PORT_CONFIG_ENTRY_RSVD_LEN 1
+#define PORT_CONFIG_ENTRY_RSVD_LBN 24
+#define PORT_CONFIG_ENTRY_RSVD_WIDTH 8
+/* Bitmask of KR lanes used by the port */
+#define PORT_CONFIG_ENTRY_LANES_OFST 4
+#define PORT_CONFIG_ENTRY_LANES_LBN 32
+#define PORT_CONFIG_ENTRY_LANES_WIDTH 32
+/* Port capabilities (MC_CMD_PHY_CAP_*) */
+#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_OFST 8
+#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_LBN 64
+#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_WIDTH 32
+/* Reserved (align to 16 bytes) */
+#define PORT_CONFIG_ENTRY_RSVD2_OFST 12
+#define PORT_CONFIG_ENTRY_RSVD2_LBN 96
+#define PORT_CONFIG_ENTRY_RSVD2_WIDTH 32
/***********************************/
-/* MC_CMD_FILTER_OP
+/* MC_CMD_FILTER_OP
+ * Multiplexed MCDI call for filter operations
*/
-#define MC_CMD_FILTER_OP 0x61
+#define MC_CMD_FILTER_OP 0x8a
+#undef MC_CMD_0x8a_PRIVILEGE_CTG
+
+#define MC_CMD_0x8a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FILTER_OP_IN msgrequest */
-#define MC_CMD_FILTER_OP_IN_LEN 100
+#define MC_CMD_FILTER_OP_IN_LEN 108
+/* identifies the type of operation requested */
#define MC_CMD_FILTER_OP_IN_OP_OFST 0
-#define MC_CMD_FILTER_OP_IN_OP_INSERT 0x0 /* enum */
-#define MC_CMD_FILTER_OP_IN_OP_REMOVE 0x1 /* enum */
-#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE 0x2 /* enum */
-#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE 0x3 /* enum */
+/* enum: single-recipient filter insert */
+#define MC_CMD_FILTER_OP_IN_OP_INSERT 0x0
+/* enum: single-recipient filter remove */
+#define MC_CMD_FILTER_OP_IN_OP_REMOVE 0x1
+/* enum: multi-recipient filter subscribe */
+#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE 0x2
+/* enum: multi-recipient filter unsubscribe */
+#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE 0x3
+/* enum: replace one recipient with another (warning - the filter handle may
+ * change)
+ */
+#define MC_CMD_FILTER_OP_IN_OP_REPLACE 0x4
+/* filter handle (for remove / unsubscribe operations) */
#define MC_CMD_FILTER_OP_IN_HANDLE_OFST 4
-#define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_OFST 8
+#define MC_CMD_FILTER_OP_IN_HANDLE_LEN 8
+#define MC_CMD_FILTER_OP_IN_HANDLE_LO_OFST 4
+#define MC_CMD_FILTER_OP_IN_HANDLE_HI_OFST 8
+/* The port ID associated with the v-adaptor which should contain this filter.
+ */
+#define MC_CMD_FILTER_OP_IN_PORT_ID_OFST 12
+/* fields to include in match criteria */
+#define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_LBN 0
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_WIDTH 1
#define MC_CMD_FILTER_OP_IN_MATCH_DST_IP_LBN 1
@@ -4796,63 +8302,493 @@
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF0_WIDTH 1
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_LBN 11
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_WIDTH 1
-#define MC_CMD_FILTER_OP_IN_RX_DEST_OFST 12
-#define MC_CMD_FILTER_OP_IN_RX_DEST_DROP 0x0 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST 0x1 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_DEST_MC 0x2 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_DEST_TX0 0x3 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_DEST_TX1 0x4 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_QUEUE_OFST 16
-#define MC_CMD_FILTER_OP_IN_RX_FLAGS_OFST 20
-#define MC_CMD_FILTER_OP_IN_RX_FLAG_RSS_LBN 0
-#define MC_CMD_FILTER_OP_IN_RX_FLAG_RSS_WIDTH 1
-#define MC_CMD_FILTER_OP_IN_RSS_CONTEXT_OFST 24
-#define MC_CMD_FILTER_OP_IN_TX_DOMAIN_OFST 28
-#define MC_CMD_FILTER_OP_IN_TX_DEST_OFST 32
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN 30
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN 31
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1
+/* receive destination */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_OFST 20
+/* enum: drop packets */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_DROP 0x0
+/* enum: receive to host */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST 0x1
+/* enum: receive to MC */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_MC 0x2
+/* enum: loop back to TXDP 0 */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_TX0 0x3
+/* enum: loop back to TXDP 1 */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_TX1 0x4
+/* receive queue handle (for multiple queue modes, this is the base queue) */
+#define MC_CMD_FILTER_OP_IN_RX_QUEUE_OFST 24
+/* receive mode */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_OFST 28
+/* enum: receive to just the specified queue */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE 0x0
+/* enum: receive to multiple queues using RSS context */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_RSS 0x1
+/* enum: receive to multiple queues using .1p mapping */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_DOT1P_MAPPING 0x2
+/* enum: install a filter entry that will never match; for test purposes only
+ */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000
+/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for
+ * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or
+ * MC_CMD_DOT1P_MAPPING_ALLOC.
+ */
+#define MC_CMD_FILTER_OP_IN_RX_CONTEXT_OFST 32
+/* transmit domain (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_IN_TX_DOMAIN_OFST 36
+/* transmit destination (either set the MAC and/or PM bits for explicit
+ * control, or set this field to TX_DEST_DEFAULT for sensible default
+ * behaviour)
+ */
+#define MC_CMD_FILTER_OP_IN_TX_DEST_OFST 40
+/* enum: request default behaviour (based on filter type) */
+#define MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT 0xffffffff
#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_LBN 0
#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_WIDTH 1
#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_LBN 1
#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_WIDTH 1
-#define MC_CMD_FILTER_OP_IN_SRC_MAC_OFST 36
+/* source MAC address to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_SRC_MAC_OFST 44
#define MC_CMD_FILTER_OP_IN_SRC_MAC_LEN 6
-#define MC_CMD_FILTER_OP_IN_SRC_PORT_OFST 42
+/* source port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_SRC_PORT_OFST 50
#define MC_CMD_FILTER_OP_IN_SRC_PORT_LEN 2
-#define MC_CMD_FILTER_OP_IN_DST_MAC_OFST 44
+/* destination MAC address to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_DST_MAC_OFST 52
#define MC_CMD_FILTER_OP_IN_DST_MAC_LEN 6
-#define MC_CMD_FILTER_OP_IN_DST_PORT_OFST 50
+/* destination port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_DST_PORT_OFST 58
#define MC_CMD_FILTER_OP_IN_DST_PORT_LEN 2
-#define MC_CMD_FILTER_OP_IN_ETHER_TYPE_OFST 52
+/* Ethernet type to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_ETHER_TYPE_OFST 60
#define MC_CMD_FILTER_OP_IN_ETHER_TYPE_LEN 2
-#define MC_CMD_FILTER_OP_IN_INNER_VLAN_OFST 54
+/* Inner VLAN tag to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_INNER_VLAN_OFST 62
#define MC_CMD_FILTER_OP_IN_INNER_VLAN_LEN 2
-#define MC_CMD_FILTER_OP_IN_OUTER_VLAN_OFST 56
+/* Outer VLAN tag to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_OUTER_VLAN_OFST 64
#define MC_CMD_FILTER_OP_IN_OUTER_VLAN_LEN 2
-#define MC_CMD_FILTER_OP_IN_IP_PROTO_OFST 58
+/* IP protocol to match (in low byte; set high byte to 0) */
+#define MC_CMD_FILTER_OP_IN_IP_PROTO_OFST 66
#define MC_CMD_FILTER_OP_IN_IP_PROTO_LEN 2
-#define MC_CMD_FILTER_OP_IN_FWDEF0_OFST 60
-#define MC_CMD_FILTER_OP_IN_FWDEF1_OFST 64
-#define MC_CMD_FILTER_OP_IN_SRC_IP_OFST 68
+/* Firmware defined register 0 to match (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_IN_FWDEF0_OFST 68
+/* Firmware defined register 1 to match (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_IN_FWDEF1_OFST 72
+/* source IP address to match (as bytes in network order; set last 12 bytes to
+ * 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_IN_SRC_IP_OFST 76
#define MC_CMD_FILTER_OP_IN_SRC_IP_LEN 16
-#define MC_CMD_FILTER_OP_IN_DST_IP_OFST 84
+/* destination IP address to match (as bytes in network order; set last 12
+ * bytes to 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_IN_DST_IP_OFST 92
#define MC_CMD_FILTER_OP_IN_DST_IP_LEN 16
+/* MC_CMD_FILTER_OP_EXT_IN msgrequest: Extension to MC_CMD_FILTER_OP_IN to
+ * include handling of VXLAN/NVGRE encapsulated frame filtering (which is
+ * supported on Medford only).
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_LEN 172
+/* identifies the type of operation requested */
+#define MC_CMD_FILTER_OP_EXT_IN_OP_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_FILTER_OP_IN/OP */
+/* filter handle (for remove / unsubscribe operations) */
+#define MC_CMD_FILTER_OP_EXT_IN_HANDLE_OFST 4
+#define MC_CMD_FILTER_OP_EXT_IN_HANDLE_LEN 8
+#define MC_CMD_FILTER_OP_EXT_IN_HANDLE_LO_OFST 4
+#define MC_CMD_FILTER_OP_EXT_IN_HANDLE_HI_OFST 8
+/* The port ID associated with the v-adaptor which should contain this filter.
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_PORT_ID_OFST 12
+/* fields to include in match criteria */
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FIELDS_OFST 16
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_LBN 0
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_IP_LBN 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_MAC_LBN 2
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_PORT_LBN 3
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_MAC_LBN 4
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_PORT_LBN 5
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_LBN 6
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_INNER_VLAN_LBN 7
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_OUTER_VLAN_LBN 8
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_LBN 9
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FWDEF0_LBN 10
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_VNI_OR_VSID_LBN 11
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_VNI_OR_VSID_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_IP_LBN 12
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_IP_LBN 13
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_MAC_LBN 14
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_PORT_LBN 15
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_MAC_LBN 16
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_PORT_LBN 17
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ETHER_TYPE_LBN 18
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_INNER_VLAN_LBN 19
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_OUTER_VLAN_LBN 20
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_IP_PROTO_LBN 21
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF0_LBN 22
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF1_LBN 23
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF1_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN 24
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN 25
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_LBN 30
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_LBN 31
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1
+/* receive destination */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_OFST 20
+/* enum: drop packets */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_DROP 0x0
+/* enum: receive to host */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_HOST 0x1
+/* enum: receive to MC */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_MC 0x2
+/* enum: loop back to TXDP 0 */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX0 0x3
+/* enum: loop back to TXDP 1 */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX1 0x4
+/* receive queue handle (for multiple queue modes, this is the base queue) */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_QUEUE_OFST 24
+/* receive mode */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_OFST 28
+/* enum: receive to just the specified queue */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_SIMPLE 0x0
+/* enum: receive to multiple queues using RSS context */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_RSS 0x1
+/* enum: receive to multiple queues using .1p mapping */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_DOT1P_MAPPING 0x2
+/* enum: install a filter entry that will never match; for test purposes only
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000
+/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for
+ * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or
+ * MC_CMD_DOT1P_MAPPING_ALLOC.
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_CONTEXT_OFST 32
+/* transmit domain (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DOMAIN_OFST 36
+/* transmit destination (either set the MAC and/or PM bits for explicit
+ * control, or set this field to TX_DEST_DEFAULT for sensible default
+ * behaviour)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_OFST 40
+/* enum: request default behaviour (based on filter type) */
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_DEFAULT 0xffffffff
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_LBN 0
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_LBN 1
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_WIDTH 1
+/* source MAC address to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_MAC_OFST 44
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_MAC_LEN 6
+/* source port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_PORT_OFST 50
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_PORT_LEN 2
+/* destination MAC address to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_DST_MAC_OFST 52
+#define MC_CMD_FILTER_OP_EXT_IN_DST_MAC_LEN 6
+/* destination port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_DST_PORT_OFST 58
+#define MC_CMD_FILTER_OP_EXT_IN_DST_PORT_LEN 2
+/* Ethernet type to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_ETHER_TYPE_OFST 60
+#define MC_CMD_FILTER_OP_EXT_IN_ETHER_TYPE_LEN 2
+/* Inner VLAN tag to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_INNER_VLAN_OFST 62
+#define MC_CMD_FILTER_OP_EXT_IN_INNER_VLAN_LEN 2
+/* Outer VLAN tag to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_OUTER_VLAN_OFST 64
+#define MC_CMD_FILTER_OP_EXT_IN_OUTER_VLAN_LEN 2
+/* IP protocol to match (in low byte; set high byte to 0) */
+#define MC_CMD_FILTER_OP_EXT_IN_IP_PROTO_OFST 66
+#define MC_CMD_FILTER_OP_EXT_IN_IP_PROTO_LEN 2
+/* Firmware defined register 0 to match (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_EXT_IN_FWDEF0_OFST 68
+/* VNI (for VXLAN/Geneve, when IP protocol is UDP) or VSID (for NVGRE, when IP
+ * protocol is GRE) to match (as bytes in network order; set last byte to 0 for
+ * VXLAN/NVGRE, or 1 for Geneve)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_OR_VSID_OFST 72
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_LBN 0
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_WIDTH 24
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_LBN 24
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_WIDTH 8
+/* enum: Match VXLAN traffic with this VNI */
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_VXLAN 0x0
+/* enum: Match Geneve traffic with this VNI */
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_GENEVE 0x1
+/* enum: Reserved for experimental development use */
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_EXPERIMENTAL 0xfe
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_LBN 0
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_WIDTH 24
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_LBN 24
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_WIDTH 8
+/* enum: Match NVGRE traffic with this VSID */
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_NVGRE 0x0
+/* source IP address to match (as bytes in network order; set last 12 bytes to
+ * 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_IP_OFST 76
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_IP_LEN 16
+/* destination IP address to match (as bytes in network order; set last 12
+ * bytes to 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_DST_IP_OFST 92
+#define MC_CMD_FILTER_OP_EXT_IN_DST_IP_LEN 16
+/* VXLAN/NVGRE inner frame source MAC address to match (as bytes in network
+ * order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_MAC_OFST 108
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_MAC_LEN 6
+/* VXLAN/NVGRE inner frame source port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_PORT_OFST 114
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_PORT_LEN 2
+/* VXLAN/NVGRE inner frame destination MAC address to match (as bytes in
+ * network order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_MAC_OFST 116
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_MAC_LEN 6
+/* VXLAN/NVGRE inner frame destination port to match (as bytes in network
+ * order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_PORT_OFST 122
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_PORT_LEN 2
+/* VXLAN/NVGRE inner frame Ethernet type to match (as bytes in network order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_ETHER_TYPE_OFST 124
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_ETHER_TYPE_LEN 2
+/* VXLAN/NVGRE inner frame Inner VLAN tag to match (as bytes in network order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_INNER_VLAN_OFST 126
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_INNER_VLAN_LEN 2
+/* VXLAN/NVGRE inner frame Outer VLAN tag to match (as bytes in network order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_OUTER_VLAN_OFST 128
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_OUTER_VLAN_LEN 2
+/* VXLAN/NVGRE inner frame IP protocol to match (in low byte; set high byte to
+ * 0)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_IP_PROTO_OFST 130
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_IP_PROTO_LEN 2
+/* VXLAN/NVGRE inner frame Firmware defined register 0 to match (reserved; set
+ * to 0)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_FWDEF0_OFST 132
+/* VXLAN/NVGRE inner frame Firmware defined register 1 to match (reserved; set
+ * to 0)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_FWDEF1_OFST 136
+/* VXLAN/NVGRE inner frame source IP address to match (as bytes in network
+ * order; set last 12 bytes to 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_IP_OFST 140
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_IP_LEN 16
+/* VXLAN/NVGRE inner frame destination IP address to match (as bytes in network
+ * order; set last 12 bytes to 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_IP_OFST 156
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_IP_LEN 16
+
/* MC_CMD_FILTER_OP_OUT msgresponse */
-#define MC_CMD_FILTER_OP_OUT_LEN 8
+#define MC_CMD_FILTER_OP_OUT_LEN 12
+/* identifies the type of operation requested */
#define MC_CMD_FILTER_OP_OUT_OP_OFST 0
-#define MC_CMD_FILTER_OP_OUT_OP_INSERT 0x0 /* enum */
-#define MC_CMD_FILTER_OP_OUT_OP_REMOVE 0x1 /* enum */
-#define MC_CMD_FILTER_OP_OUT_OP_SUBSCRIBE 0x2 /* enum */
-#define MC_CMD_FILTER_OP_OUT_OP_UNSUBSCRIBE 0x3 /* enum */
+/* Enum values, see field(s): */
+/* MC_CMD_FILTER_OP_IN/OP */
+/* Returned filter handle (for insert / subscribe operations). Note that these
+ * handles should be considered opaque to the host, although a value of
+ * 0xFFFFFFFF_FFFFFFFF is guaranteed never to be a valid handle.
+ */
#define MC_CMD_FILTER_OP_OUT_HANDLE_OFST 4
+#define MC_CMD_FILTER_OP_OUT_HANDLE_LEN 8
+#define MC_CMD_FILTER_OP_OUT_HANDLE_LO_OFST 4
+#define MC_CMD_FILTER_OP_OUT_HANDLE_HI_OFST 8
+/* enum: guaranteed invalid filter handle (low 32 bits) */
+#define MC_CMD_FILTER_OP_OUT_HANDLE_LO_INVALID 0xffffffff
+/* enum: guaranteed invalid filter handle (high 32 bits) */
+#define MC_CMD_FILTER_OP_OUT_HANDLE_HI_INVALID 0xffffffff
+
+/* MC_CMD_FILTER_OP_EXT_OUT msgresponse */
+#define MC_CMD_FILTER_OP_EXT_OUT_LEN 12
+/* identifies the type of operation requested */
+#define MC_CMD_FILTER_OP_EXT_OUT_OP_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_FILTER_OP_EXT_IN/OP */
+/* Returned filter handle (for insert / subscribe operations). Note that these
+ * handles should be considered opaque to the host, although a value of
+ * 0xFFFFFFFF_FFFFFFFF is guaranteed never to be a valid handle.
+ */
+#define MC_CMD_FILTER_OP_EXT_OUT_HANDLE_OFST 4
+#define MC_CMD_FILTER_OP_EXT_OUT_HANDLE_LEN 8
+#define MC_CMD_FILTER_OP_EXT_OUT_HANDLE_LO_OFST 4
+#define MC_CMD_FILTER_OP_EXT_OUT_HANDLE_HI_OFST 8
+/* Enum values, see field(s): */
+/* MC_CMD_FILTER_OP_OUT/HANDLE */
+
+
+/***********************************/
+/* MC_CMD_GET_PARSER_DISP_INFO
+ * Get information related to the parser-dispatcher subsystem
+ */
+#define MC_CMD_GET_PARSER_DISP_INFO 0xe4
+#undef MC_CMD_0xe4_PRIVILEGE_CTG
+
+#define MC_CMD_0xe4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_PARSER_DISP_INFO_IN msgrequest */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_LEN 4
+/* identifies the type of operation requested */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_OFST 0
+/* enum: read the list of supported RX filter matches */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES 0x1
+/* enum: read flags indicating restrictions on filter insertion for the calling
+ * client
+ */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_RESTRICTIONS 0x2
+
+/* MC_CMD_GET_PARSER_DISP_INFO_OUT msgresponse */
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMIN 8
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX 252
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LEN(num) (8+4*(num))
+/* identifies the type of operation requested */
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_OP_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_GET_PARSER_DISP_INFO_IN/OP */
+/* number of supported match types */
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_NUM_SUPPORTED_MATCHES_OFST 4
+/* array of supported match types (valid MATCH_FIELDS values for
+ * MC_CMD_FILTER_OP) sorted in decreasing priority order
+ */
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_OFST 8
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_LEN 4
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MINNUM 0
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MAXNUM 61
+
+/* MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT msgresponse */
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_LEN 8
+/* identifies the type of operation requested */
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_OP_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_GET_PARSER_DISP_INFO_IN/OP */
+/* bitfield of filter insertion restrictions */
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_RESTRICTION_FLAGS_OFST 4
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_LBN 0
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_WIDTH 1
+
+
+/***********************************/
+/* MC_CMD_PARSER_DISP_RW
+ * Direct read/write of parser-dispatcher state (DICPUs and LUE) for debugging
+ */
+#define MC_CMD_PARSER_DISP_RW 0xe5
+#undef MC_CMD_0xe5_PRIVILEGE_CTG
+
+#define MC_CMD_0xe5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_PARSER_DISP_RW_IN msgrequest */
+#define MC_CMD_PARSER_DISP_RW_IN_LEN 32
+/* identifies the target of the operation */
+#define MC_CMD_PARSER_DISP_RW_IN_TARGET_OFST 0
+/* enum: RX dispatcher CPU */
+#define MC_CMD_PARSER_DISP_RW_IN_RX_DICPU 0x0
+/* enum: TX dispatcher CPU */
+#define MC_CMD_PARSER_DISP_RW_IN_TX_DICPU 0x1
+/* enum: Lookup engine (with original metadata format) */
+#define MC_CMD_PARSER_DISP_RW_IN_LUE 0x2
+/* enum: Lookup engine (with requested metadata format) */
+#define MC_CMD_PARSER_DISP_RW_IN_LUE_VERSIONED_METADATA 0x3
+/* identifies the type of operation requested */
+#define MC_CMD_PARSER_DISP_RW_IN_OP_OFST 4
+/* enum: read a word of DICPU DMEM or a LUE entry */
+#define MC_CMD_PARSER_DISP_RW_IN_READ 0x0
+/* enum: write a word of DICPU DMEM or a LUE entry */
+#define MC_CMD_PARSER_DISP_RW_IN_WRITE 0x1
+/* enum: read-modify-write a word of DICPU DMEM (not valid for LUE) */
+#define MC_CMD_PARSER_DISP_RW_IN_RMW 0x2
+/* data memory address or LUE index */
+#define MC_CMD_PARSER_DISP_RW_IN_ADDRESS_OFST 8
+/* value to write (for DMEM writes) */
+#define MC_CMD_PARSER_DISP_RW_IN_DMEM_WRITE_VALUE_OFST 12
+/* XOR value (for DMEM read-modify-writes: new = (old & mask) ^ value) */
+#define MC_CMD_PARSER_DISP_RW_IN_DMEM_RMW_XOR_VALUE_OFST 12
+/* AND mask (for DMEM read-modify-writes: new = (old & mask) ^ value) */
+#define MC_CMD_PARSER_DISP_RW_IN_DMEM_RMW_AND_MASK_OFST 16
+/* metadata format (for LUE reads using LUE_VERSIONED_METADATA) */
+#define MC_CMD_PARSER_DISP_RW_IN_LUE_READ_METADATA_VERSION_OFST 12
+/* value to write (for LUE writes) */
+#define MC_CMD_PARSER_DISP_RW_IN_LUE_WRITE_VALUE_OFST 12
+#define MC_CMD_PARSER_DISP_RW_IN_LUE_WRITE_VALUE_LEN 20
+
+/* MC_CMD_PARSER_DISP_RW_OUT msgresponse */
+#define MC_CMD_PARSER_DISP_RW_OUT_LEN 52
+/* value read (for DMEM reads) */
+#define MC_CMD_PARSER_DISP_RW_OUT_DMEM_READ_VALUE_OFST 0
+/* value read (for LUE reads) */
+#define MC_CMD_PARSER_DISP_RW_OUT_LUE_READ_VALUE_OFST 0
+#define MC_CMD_PARSER_DISP_RW_OUT_LUE_READ_VALUE_LEN 20
+/* up to 8 32-bit words of additional soft state from the LUE manager (the
+ * exact content is firmware-dependent and intended only for debug use)
+ */
+#define MC_CMD_PARSER_DISP_RW_OUT_LUE_MGR_STATE_OFST 20
+#define MC_CMD_PARSER_DISP_RW_OUT_LUE_MGR_STATE_LEN 32
/***********************************/
-/* MC_CMD_SET_PF_COUNT
+/* MC_CMD_GET_PF_COUNT
+ * Get number of PFs on the device.
*/
-#define MC_CMD_SET_PF_COUNT 0x62
+#define MC_CMD_GET_PF_COUNT 0xb6
+#undef MC_CMD_0xb6_PRIVILEGE_CTG
+
+#define MC_CMD_0xb6_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_PF_COUNT_IN msgrequest */
+#define MC_CMD_GET_PF_COUNT_IN_LEN 0
+
+/* MC_CMD_GET_PF_COUNT_OUT msgresponse */
+#define MC_CMD_GET_PF_COUNT_OUT_LEN 1
+/* Identifies the number of PFs on the device. */
+#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST 0
+#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_LEN 1
+
+
+/***********************************/
+/* MC_CMD_SET_PF_COUNT
+ * Set number of PFs on the device.
+ */
+#define MC_CMD_SET_PF_COUNT 0xb7
/* MC_CMD_SET_PF_COUNT_IN msgrequest */
#define MC_CMD_SET_PF_COUNT_IN_LEN 4
+/* New number of PFs on the device. */
#define MC_CMD_SET_PF_COUNT_IN_PF_COUNT_OFST 0
/* MC_CMD_SET_PF_COUNT_OUT msgresponse */
@@ -4860,25 +8796,35 @@
/***********************************/
-/* MC_CMD_GET_PORT_ASSIGNMENT
+/* MC_CMD_GET_PORT_ASSIGNMENT
+ * Get port assignment for current PCI function.
*/
-#define MC_CMD_GET_PORT_ASSIGNMENT 0x63
+#define MC_CMD_GET_PORT_ASSIGNMENT 0xb8
+#undef MC_CMD_0xb8_PRIVILEGE_CTG
+
+#define MC_CMD_0xb8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_PORT_ASSIGNMENT_IN msgrequest */
#define MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN 0
/* MC_CMD_GET_PORT_ASSIGNMENT_OUT msgresponse */
#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN 4
+/* Identifies the port assignment for this function. */
#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_PORT_OFST 0
/***********************************/
-/* MC_CMD_SET_PORT_ASSIGNMENT
+/* MC_CMD_SET_PORT_ASSIGNMENT
+ * Set port assignment for current PCI function.
*/
-#define MC_CMD_SET_PORT_ASSIGNMENT 0x64
+#define MC_CMD_SET_PORT_ASSIGNMENT 0xb9
+#undef MC_CMD_0xb9_PRIVILEGE_CTG
+
+#define MC_CMD_0xb9_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_PORT_ASSIGNMENT_IN msgrequest */
#define MC_CMD_SET_PORT_ASSIGNMENT_IN_LEN 4
+/* Identifies the port assignment for this function. */
#define MC_CMD_SET_PORT_ASSIGNMENT_IN_PORT_OFST 0
/* MC_CMD_SET_PORT_ASSIGNMENT_OUT msgresponse */
@@ -4886,22 +8832,53 @@
/***********************************/
-/* MC_CMD_ALLOC_VIS
+/* MC_CMD_ALLOC_VIS
+ * Allocate VIs for current PCI function.
*/
-#define MC_CMD_ALLOC_VIS 0x65
+#define MC_CMD_ALLOC_VIS 0x8b
+#undef MC_CMD_0x8b_PRIVILEGE_CTG
-/* MC_CMD_ALLOC_VIS_IN msgrequest */
-#define MC_CMD_ALLOC_VIS_IN_LEN 4
-#define MC_CMD_ALLOC_VIS_IN_VI_COUNT_OFST 0
+#define MC_CMD_0x8b_PRIVILEGE_CTG SRIOV_CTG_GENERAL
-/* MC_CMD_ALLOC_VIS_OUT msgresponse */
-#define MC_CMD_ALLOC_VIS_OUT_LEN 0
+/* MC_CMD_ALLOC_VIS_IN msgrequest */
+#define MC_CMD_ALLOC_VIS_IN_LEN 8
+/* The minimum number of VIs that is acceptable */
+#define MC_CMD_ALLOC_VIS_IN_MIN_VI_COUNT_OFST 0
+/* The maximum number of VIs that would be useful */
+#define MC_CMD_ALLOC_VIS_IN_MAX_VI_COUNT_OFST 4
+
+/* MC_CMD_ALLOC_VIS_OUT msgresponse: Huntington-compatible VI_ALLOC request.
+ * Use extended version in new code.
+ */
+#define MC_CMD_ALLOC_VIS_OUT_LEN 8
+/* The number of VIs allocated on this function */
+#define MC_CMD_ALLOC_VIS_OUT_VI_COUNT_OFST 0
+/* The base absolute VI number allocated to this function. Required to
+ * correctly interpret wakeup events.
+ */
+#define MC_CMD_ALLOC_VIS_OUT_VI_BASE_OFST 4
+
+/* MC_CMD_ALLOC_VIS_EXT_OUT msgresponse */
+#define MC_CMD_ALLOC_VIS_EXT_OUT_LEN 12
+/* The number of VIs allocated on this function */
+#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_COUNT_OFST 0
+/* The base absolute VI number allocated to this function. Required to
+ * correctly interpret wakeup events.
+ */
+#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_BASE_OFST 4
+/* Function's port vi_shift value (always 0 on Huntington) */
+#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_SHIFT_OFST 8
/***********************************/
-/* MC_CMD_FREE_VIS
+/* MC_CMD_FREE_VIS
+ * Free VIs for current PCI function. Any linked PIO buffers will be unlinked,
+ * but not freed.
*/
-#define MC_CMD_FREE_VIS 0x66
+#define MC_CMD_FREE_VIS 0x8c
+#undef MC_CMD_0x8c_PRIVILEGE_CTG
+
+#define MC_CMD_0x8c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FREE_VIS_IN msgrequest */
#define MC_CMD_FREE_VIS_IN_LEN 0
@@ -4911,37 +8888,57 @@
/***********************************/
-/* MC_CMD_GET_SRIOV_CFG
+/* MC_CMD_GET_SRIOV_CFG
+ * Get SRIOV config for this PF.
*/
-#define MC_CMD_GET_SRIOV_CFG 0x67
+#define MC_CMD_GET_SRIOV_CFG 0xba
+#undef MC_CMD_0xba_PRIVILEGE_CTG
+
+#define MC_CMD_0xba_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_SRIOV_CFG_IN msgrequest */
#define MC_CMD_GET_SRIOV_CFG_IN_LEN 0
/* MC_CMD_GET_SRIOV_CFG_OUT msgresponse */
#define MC_CMD_GET_SRIOV_CFG_OUT_LEN 20
+/* Number of VFs currently enabled. */
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_CURRENT_OFST 0
+/* Max number of VFs before sriov stride and offset may need to be changed. */
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_MAX_OFST 4
#define MC_CMD_GET_SRIOV_CFG_OUT_FLAGS_OFST 8
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_LBN 0
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_WIDTH 1
+/* RID offset of first VF from PF. */
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_OFFSET_OFST 12
+/* RID offset of each subsequent VF from the previous. */
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_STRIDE_OFST 16
/***********************************/
-/* MC_CMD_SET_SRIOV_CFG
+/* MC_CMD_SET_SRIOV_CFG
+ * Set SRIOV config for this PF.
*/
-#define MC_CMD_SET_SRIOV_CFG 0x68
+#define MC_CMD_SET_SRIOV_CFG 0xbb
+#undef MC_CMD_0xbb_PRIVILEGE_CTG
+
+#define MC_CMD_0xbb_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_SRIOV_CFG_IN msgrequest */
#define MC_CMD_SET_SRIOV_CFG_IN_LEN 20
+/* Number of VFs currently enabled. */
#define MC_CMD_SET_SRIOV_CFG_IN_VF_CURRENT_OFST 0
+/* Max number of VFs before sriov stride and offset may need to be changed. */
#define MC_CMD_SET_SRIOV_CFG_IN_VF_MAX_OFST 4
#define MC_CMD_SET_SRIOV_CFG_IN_FLAGS_OFST 8
#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_LBN 0
#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_WIDTH 1
+/* RID offset of first VF from PF, or 0 for no change, or
+ * MC_CMD_RESOURCE_INSTANCE_ANY to allow the system to allocate an offset.
+ */
#define MC_CMD_SET_SRIOV_CFG_IN_VF_OFFSET_OFST 12
+/* RID offset of each subsequent VF from the previous, 0 for no change, or
+ * MC_CMD_RESOURCE_INSTANCE_ANY to allow the system to allocate a stride.
+ */
#define MC_CMD_SET_SRIOV_CFG_IN_VF_STRIDE_OFST 16
/* MC_CMD_SET_SRIOV_CFG_OUT msgresponse */
@@ -4949,68 +8946,172 @@
/***********************************/
-/* MC_CMD_GET_VI_COUNT
+/* MC_CMD_GET_VI_ALLOC_INFO
+ * Get information about number of VI's and base VI number allocated to this
+ * function.
*/
-#define MC_CMD_GET_VI_COUNT 0x69
+#define MC_CMD_GET_VI_ALLOC_INFO 0x8d
+#undef MC_CMD_0x8d_PRIVILEGE_CTG
-/* MC_CMD_GET_VI_COUNT_IN msgrequest */
-#define MC_CMD_GET_VI_COUNT_IN_LEN 0
+#define MC_CMD_0x8d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
-/* MC_CMD_GET_VI_COUNT_OUT msgresponse */
-#define MC_CMD_GET_VI_COUNT_OUT_LEN 4
-#define MC_CMD_GET_VI_COUNT_OUT_VI_COUNT_OFST 0
+/* MC_CMD_GET_VI_ALLOC_INFO_IN msgrequest */
+#define MC_CMD_GET_VI_ALLOC_INFO_IN_LEN 0
-
-/***********************************/
-/* MC_CMD_GET_VECTOR_CFG
+/* MC_CMD_GET_VI_ALLOC_INFO_OUT msgresponse */
+#define MC_CMD_GET_VI_ALLOC_INFO_OUT_LEN 12
+/* The number of VIs allocated on this function */
+#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_COUNT_OFST 0
+/* The base absolute VI number allocated to this function. Required to
+ * correctly interpret wakeup events.
*/
-#define MC_CMD_GET_VECTOR_CFG 0x70
-
-/* MC_CMD_GET_VECTOR_CFG_IN msgrequest */
-#define MC_CMD_GET_VECTOR_CFG_IN_LEN 0
-
-/* MC_CMD_GET_VECTOR_CFG_OUT msgresponse */
-#define MC_CMD_GET_VECTOR_CFG_OUT_LEN 12
-#define MC_CMD_GET_VECTOR_CFG_OUT_VEC_BASE_OFST 0
-#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_PF_OFST 4
-#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_VF_OFST 8
+#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_BASE_OFST 4
+/* Function's port vi_shift value (always 0 on Huntington) */
+#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_SHIFT_OFST 8
/***********************************/
-/* MC_CMD_SET_VECTOR_CFG
+/* MC_CMD_DUMP_VI_STATE
+ * For CmdClient use. Dump pertinent information on a specific absolute VI.
*/
-#define MC_CMD_SET_VECTOR_CFG 0x71
-
-/* MC_CMD_SET_VECTOR_CFG_IN msgrequest */
-#define MC_CMD_SET_VECTOR_CFG_IN_LEN 12
-#define MC_CMD_SET_VECTOR_CFG_IN_VEC_BASE_OFST 0
-#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_PF_OFST 4
-#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_VF_OFST 8
-
-/* MC_CMD_SET_VECTOR_CFG_OUT msgresponse */
-#define MC_CMD_SET_VECTOR_CFG_OUT_LEN 0
+#define MC_CMD_DUMP_VI_STATE 0x8e
+#undef MC_CMD_0x8e_PRIVILEGE_CTG
+
+#define MC_CMD_0x8e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_DUMP_VI_STATE_IN msgrequest */
+#define MC_CMD_DUMP_VI_STATE_IN_LEN 4
+/* The VI number to query. */
+#define MC_CMD_DUMP_VI_STATE_IN_VI_NUMBER_OFST 0
+
+/* MC_CMD_DUMP_VI_STATE_OUT msgresponse */
+#define MC_CMD_DUMP_VI_STATE_OUT_LEN 96
+/* The PF part of the function owning this VI. */
+#define MC_CMD_DUMP_VI_STATE_OUT_OWNER_PF_OFST 0
+#define MC_CMD_DUMP_VI_STATE_OUT_OWNER_PF_LEN 2
+/* The VF part of the function owning this VI. */
+#define MC_CMD_DUMP_VI_STATE_OUT_OWNER_VF_OFST 2
+#define MC_CMD_DUMP_VI_STATE_OUT_OWNER_VF_LEN 2
+/* Base of VIs allocated to this function. */
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VI_BASE_OFST 4
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VI_BASE_LEN 2
+/* Count of VIs allocated to the owner function. */
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VI_COUNT_OFST 6
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VI_COUNT_LEN 2
+/* Base interrupt vector allocated to this function. */
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VECTOR_BASE_OFST 8
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VECTOR_BASE_LEN 2
+/* Number of interrupt vectors allocated to this function. */
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VECTOR_COUNT_OFST 10
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VECTOR_COUNT_LEN 2
+/* Raw evq ptr table data. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EVQ_PTR_RAW_OFST 12
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EVQ_PTR_RAW_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EVQ_PTR_RAW_LO_OFST 12
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EVQ_PTR_RAW_HI_OFST 16
+/* Raw evq timer table data. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_OFST 20
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_LO_OFST 20
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_HI_OFST 24
+/* Combined metadata field. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_OFST 28
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_LBN 0
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_NPAGES_LBN 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_WKUP_REF_LBN 24
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_WKUP_REF_WIDTH 8
+/* TXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_0_OFST 32
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_0_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_0_LO_OFST 32
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_0_HI_OFST 36
+/* TXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_1_OFST 40
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_1_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_1_LO_OFST 40
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_1_HI_OFST 44
+/* TXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_2_OFST 48
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_2_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_2_LO_OFST 48
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_2_HI_OFST 52
+/* Combined metadata field. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_OFST 56
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_LO_OFST 56
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_HI_OFST 60
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_BASE_LBN 0
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_NPAGES_LBN 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_QSTATE_LBN 24
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_QSTATE_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_WAITCOUNT_LBN 32
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_WAITCOUNT_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_PADDING_LBN 40
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_PADDING_WIDTH 24
+/* RXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_0_OFST 64
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_0_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_0_LO_OFST 64
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_0_HI_OFST 68
+/* RXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_1_OFST 72
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_1_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_1_LO_OFST 72
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_1_HI_OFST 76
+/* Reserved, currently 0. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_2_OFST 80
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_2_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_2_LO_OFST 80
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_2_HI_OFST 84
+/* Combined metadata field. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_OFST 88
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_LO_OFST 88
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_HI_OFST 92
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_BASE_LBN 0
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_NPAGES_LBN 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_QSTATE_LBN 24
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_QSTATE_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_WAITCOUNT_LBN 32
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_WAITCOUNT_WIDTH 8
/***********************************/
-/* MC_CMD_ALLOC_PIOBUF
+/* MC_CMD_ALLOC_PIOBUF
+ * Allocate a push I/O buffer for later use with a tx queue.
*/
-#define MC_CMD_ALLOC_PIOBUF 0x72
+#define MC_CMD_ALLOC_PIOBUF 0x8f
+#undef MC_CMD_0x8f_PRIVILEGE_CTG
+
+#define MC_CMD_0x8f_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_ALLOC_PIOBUF_IN msgrequest */
#define MC_CMD_ALLOC_PIOBUF_IN_LEN 0
/* MC_CMD_ALLOC_PIOBUF_OUT msgresponse */
#define MC_CMD_ALLOC_PIOBUF_OUT_LEN 4
+/* Handle for allocated push I/O buffer. */
#define MC_CMD_ALLOC_PIOBUF_OUT_PIOBUF_HANDLE_OFST 0
/***********************************/
-/* MC_CMD_FREE_PIOBUF
+/* MC_CMD_FREE_PIOBUF
+ * Free a push I/O buffer.
*/
-#define MC_CMD_FREE_PIOBUF 0x73
+#define MC_CMD_FREE_PIOBUF 0x90
+#undef MC_CMD_0x90_PRIVILEGE_CTG
+
+#define MC_CMD_0x90_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_FREE_PIOBUF_IN msgrequest */
#define MC_CMD_FREE_PIOBUF_IN_LEN 4
+/* Handle for allocated push I/O buffer. */
#define MC_CMD_FREE_PIOBUF_IN_PIOBUF_HANDLE_OFST 0
/* MC_CMD_FREE_PIOBUF_OUT msgresponse */
@@ -5018,16 +9119,499 @@
/***********************************/
-/* MC_CMD_V2_EXTN
+/* MC_CMD_GET_VI_TLP_PROCESSING
+ * Get TLP steering and ordering information for a VI.
+ */
+#define MC_CMD_GET_VI_TLP_PROCESSING 0xb0
+#undef MC_CMD_0xb0_PRIVILEGE_CTG
+
+#define MC_CMD_0xb0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_VI_TLP_PROCESSING_IN msgrequest */
+#define MC_CMD_GET_VI_TLP_PROCESSING_IN_LEN 4
+/* VI number to get information for. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_IN_INSTANCE_OFST 0
+
+/* MC_CMD_GET_VI_TLP_PROCESSING_OUT msgresponse */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_LEN 4
+/* Transaction processing steering hint 1 for use with the Rx Queue. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_TAG1_RX_OFST 0
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_TAG1_RX_LEN 1
+/* Transaction processing steering hint 2 for use with the Ev Queue. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_TAG2_EV_OFST 1
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_TAG2_EV_LEN 1
+/* Use Relaxed ordering model for TLPs on this VI. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_RELAXED_ORDERING_LBN 16
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_RELAXED_ORDERING_WIDTH 1
+/* Use ID based ordering for TLPs on this VI. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_ID_BASED_ORDERING_LBN 17
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_ID_BASED_ORDERING_WIDTH 1
+/* Set no snoop bit for TLPs on this VI. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_NO_SNOOP_LBN 18
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_NO_SNOOP_WIDTH 1
+/* Enable TPH for TLPs on this VI. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_ON_LBN 19
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_ON_WIDTH 1
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_DATA_OFST 0
+
+
+/***********************************/
+/* MC_CMD_SET_VI_TLP_PROCESSING
+ * Set TLP steering and ordering information for a VI.
+ */
+#define MC_CMD_SET_VI_TLP_PROCESSING 0xb1
+#undef MC_CMD_0xb1_PRIVILEGE_CTG
+
+#define MC_CMD_0xb1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_SET_VI_TLP_PROCESSING_IN msgrequest */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_LEN 8
+/* VI number to set information for. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_INSTANCE_OFST 0
+/* Transaction processing steering hint 1 for use with the Rx Queue. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG1_RX_OFST 4
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG1_RX_LEN 1
+/* Transaction processing steering hint 2 for use with the Ev Queue. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG2_EV_OFST 5
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG2_EV_LEN 1
+/* Use Relaxed ordering model for TLPs on this VI. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_RELAXED_ORDERING_LBN 48
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_RELAXED_ORDERING_WIDTH 1
+/* Use ID based ordering for TLPs on this VI. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_ID_BASED_ORDERING_LBN 49
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_ID_BASED_ORDERING_WIDTH 1
+/* Set the no snoop bit for TLPs on this VI. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_NO_SNOOP_LBN 50
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_NO_SNOOP_WIDTH 1
+/* Enable TPH for TLPs on this VI. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_ON_LBN 51
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_ON_WIDTH 1
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_DATA_OFST 4
+
+/* MC_CMD_SET_VI_TLP_PROCESSING_OUT msgresponse */
+#define MC_CMD_SET_VI_TLP_PROCESSING_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS
+ * Get global PCIe steering and transaction processing configuration.
+ */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS 0xbc
+#undef MC_CMD_0xbc_PRIVILEGE_CTG
+
+#define MC_CMD_0xbc_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN msgrequest */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_LEN 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_OFST 0
+/* enum: MISC. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_MISC 0x0
+/* enum: IDO. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_IDO 0x1
+/* enum: RO. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_RO 0x2
+/* enum: TPH Type. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_TPH_TYPE 0x3
+
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT msgresponse */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_LEN 8
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_GLOBAL_CATEGORY_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN/TLP_GLOBAL_CATEGORY */
+/* Amalgamated TLP info word. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_WORD_OFST 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_LBN 0
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_SPARE_LBN 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_SPARE_WIDTH 31
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_DL_EN_LBN 0
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_DL_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_TX_EN_LBN 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_TX_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_EV_EN_LBN 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_EV_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_RX_EN_LBN 3
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_RX_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_SPARE_LBN 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_SPARE_WIDTH 28
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_RXDMA_EN_LBN 0
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_RXDMA_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_TXDMA_EN_LBN 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_TXDMA_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_DL_EN_LBN 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_DL_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_SPARE_LBN 3
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_SPARE_WIDTH 29
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_MSIX_LBN 0
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_MSIX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_DL_LBN 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_DL_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_TX_LBN 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_TX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_EV_LBN 6
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_EV_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_RX_LBN 8
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_RX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TLP_TYPE_SPARE_LBN 9
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TLP_TYPE_SPARE_WIDTH 23
+
+
+/***********************************/
+/* MC_CMD_SET_TLP_PROCESSING_GLOBALS
+ * Set global PCIe steering and transaction processing configuration.
+ */
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS 0xbd
+#undef MC_CMD_0xbd_PRIVILEGE_CTG
+
+#define MC_CMD_0xbd_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN msgrequest */
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_LEN 8
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS/MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN/TLP_GLOBAL_CATEGORY */
+/* Amalgamated TLP info word. */
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_WORD_OFST 4
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_LBN 0
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_DL_EN_LBN 0
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_DL_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_TX_EN_LBN 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_TX_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_EV_EN_LBN 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_EV_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_RX_EN_LBN 3
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_RX_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_RXDMA_EN_LBN 0
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_RXDMA_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_TXDMA_EN_LBN 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_TXDMA_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_DL_EN_LBN 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_DL_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_MSIX_LBN 0
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_MSIX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_DL_LBN 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_DL_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_TX_LBN 4
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_TX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_EV_LBN 6
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_EV_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_RX_LBN 8
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_RX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_SPARE_LBN 10
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_SPARE_WIDTH 22
+
+/* MC_CMD_SET_TLP_PROCESSING_GLOBALS_OUT msgresponse */
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SATELLITE_DOWNLOAD
+ * Download a new set of images to the satellite CPUs from the host.
+ */
+#define MC_CMD_SATELLITE_DOWNLOAD 0x91
+#undef MC_CMD_0x91_PRIVILEGE_CTG
+
+#define MC_CMD_0x91_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SATELLITE_DOWNLOAD_IN msgrequest: The reset requirements for the CPUs
+ * are subtle, and so downloads must proceed in a number of phases.
+ *
+ * 1) PHASE_RESET with a target of TARGET_ALL and chunk ID/length of 0.
+ *
+ * 2) PHASE_IMEMS for each of the IMEM targets (target IDs 0-11). Each download
+ * may consist of multiple chunks. The final chunk (with CHUNK_ID_LAST) should
+ * be a checksum (a simple 32-bit sum) of the transferred data. An individual
+ * download may be aborted using CHUNK_ID_ABORT.
+ *
+ * 3) PHASE_VECTORS for each of the vector table targets (target IDs 12-15),
+ * similar to PHASE_IMEMS.
+ *
+ * 4) PHASE_READY with a target of TARGET_ALL and chunk ID/length of 0.
+ *
+ * After any error (a requested abort is not considered to be an error) the
+ * sequence must be restarted from PHASE_RESET.
+ */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_LENMIN 20
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_LENMAX 252
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_LEN(num) (16+4*(num))
+/* Download phase. (Note: the IDLE phase is used internally and is never valid
+ * in a command from the host.)
+ */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_OFST 0
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IDLE 0x0 /* enum */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_RESET 0x1 /* enum */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IMEMS 0x2 /* enum */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_VECTORS 0x3 /* enum */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_READY 0x4 /* enum */
+/* Target for download. (These match the blob numbers defined in
+ * mc_flash_layout.h.)
+ */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_OFST 4
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_TEXT 0x0
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_TEXT 0x1
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDP_TEXT 0x2
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDP_TEXT 0x3
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_LUT 0x4
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_LUT_CFG 0x5
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_LUT 0x6
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_LUT_CFG 0x7
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_PGM 0x8
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_SL_PGM 0x9
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_PGM 0xa
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_SL_PGM 0xb
+/* enum: Valid in phase 3 (PHASE_VECTORS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_VTBL0 0xc
+/* enum: Valid in phase 3 (PHASE_VECTORS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_VTBL0 0xd
+/* enum: Valid in phase 3 (PHASE_VECTORS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_VTBL1 0xe
+/* enum: Valid in phase 3 (PHASE_VECTORS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_VTBL1 0xf
+/* enum: Valid in phases 1 (PHASE_RESET) and 4 (PHASE_READY) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_ALL 0xffffffff
+/* Chunk ID, or CHUNK_ID_LAST or CHUNK_ID_ABORT */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_OFST 8
+/* enum: Last chunk, containing checksum rather than data */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_LAST 0xffffffff
+/* enum: Abort download of this item */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_ABORT 0xfffffffe
+/* Length of this chunk in bytes */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_LEN_OFST 12
+/* Data for this chunk */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_OFST 16
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_LEN 4
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_MINNUM 1
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_MAXNUM 59
+
+/* MC_CMD_SATELLITE_DOWNLOAD_OUT msgresponse */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_LEN 8
+/* Same as MC_CMD_ERR field, but included as 0 in success cases */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_RESULT_OFST 0
+/* Extra status information */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_INFO_OFST 4
+/* enum: Code download OK, completed. */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_COMPLETE 0x0
+/* enum: Code download aborted as requested. */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_ABORTED 0x1
+/* enum: Code download OK so far, send next chunk. */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_NEXT_CHUNK 0x2
+/* enum: Download phases out of sequence */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_PHASE 0x100
+/* enum: Bad target for this phase */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_TARGET 0x101
+/* enum: Chunk ID out of sequence */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHUNK_ID 0x200
+/* enum: Chunk length zero or too large */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHUNK_LEN 0x201
+/* enum: Checksum was incorrect */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHECKSUM 0x300
+
+
+/***********************************/
+/* MC_CMD_GET_CAPABILITIES
+ * Get device capabilities.
+ *
+ * This is supplementary to the MC_CMD_GET_BOARD_CFG command, and intended to
+ * reference inherent device capabilities as opposed to current NVRAM config.
+ */
+#define MC_CMD_GET_CAPABILITIES 0xbe
+#undef MC_CMD_0xbe_PRIVILEGE_CTG
+
+#define MC_CMD_0xbe_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_CAPABILITIES_IN msgrequest */
+#define MC_CMD_GET_CAPABILITIES_IN_LEN 0
+
+/* MC_CMD_GET_CAPABILITIES_OUT msgresponse */
+#define MC_CMD_GET_CAPABILITIES_OUT_LEN 20
+/* First word of flags. */
+#define MC_CMD_GET_CAPABILITIES_OUT_FLAGS1_OFST 0
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_LBN 13
+#define MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_QBB_LBN 14
+#define MC_CMD_GET_CAPABILITIES_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_LBN 16
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_LBN 17
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_LBN 18
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_VLAN_INSERTION_LBN 19
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_VLAN_STRIPPING_LBN 20
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN 21
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_0_LBN 22
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN 23
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_TIMESTAMP_LBN 24
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN 25
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_LBN 26
+#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_LBN 27
+#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER_LBN 28
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_EVB_LBN 30
+#define MC_CMD_GET_CAPABILITIES_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN 31
+#define MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_WIDTH 1
+/* RxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_OFST 4
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_LEN 2
+/* enum: Standard RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP 0x0
+/* enum: Low latency RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_LOW_LATENCY 0x1
+/* enum: Packed stream RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_PACKED_STREAM 0x2
+/* enum: BIST RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_BIST 0x10a
+/* enum: RXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
+/* enum: RXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
+/* enum: RXDP Test firmware image 3 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
+/* enum: RXDP Test firmware image 4 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
+/* enum: RXDP Test firmware image 5 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_BACKPRESSURE 0x105
+/* enum: RXDP Test firmware image 6 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
+/* enum: RXDP Test firmware image 7 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
+/* enum: RXDP Test firmware image 8 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
+/* TxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_OFST 6
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_LEN 2
+/* enum: Standard TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP 0x0
+/* enum: Low latency TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_LOW_LATENCY 0x1
+/* enum: High packet rate TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_HIGH_PACKET_RATE 0x3
+/* enum: BIST TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_BIST 0x12d
+/* enum: TXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
+/* enum: TXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_OFST 8
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial RX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Virtual switching (full feature) RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant RX PD firmware using PM rather than MAC
+ * (Huntington development only)
*/
-#define MC_CMD_V2_EXTN 0x7f
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+/* enum: Low latency RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
+/* enum: Packed stream RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
+/* enum: RX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* enum: RX PD firmware parsing but not filtering network overlay tunnel
+ * encapsulations (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_OFST 10
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial TX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Virtual switching (full feature) TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant TX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
+/* enum: TX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* Hardware capabilities of NIC */
+#define MC_CMD_GET_CAPABILITIES_OUT_HW_CAPABILITIES_OFST 12
+/* Licensed capabilities */
+#define MC_CMD_GET_CAPABILITIES_OUT_LICENSE_CAPABILITIES_OFST 16
+
+
+/***********************************/
+/* MC_CMD_V2_EXTN
+ * Encapsulation for a v2 extended command
+ */
+#define MC_CMD_V2_EXTN 0x7f
/* MC_CMD_V2_EXTN_IN msgrequest */
#define MC_CMD_V2_EXTN_IN_LEN 4
+/* the extended command number */
#define MC_CMD_V2_EXTN_IN_EXTENDED_CMD_LBN 0
#define MC_CMD_V2_EXTN_IN_EXTENDED_CMD_WIDTH 15
#define MC_CMD_V2_EXTN_IN_UNUSED_LBN 15
#define MC_CMD_V2_EXTN_IN_UNUSED_WIDTH 1
+/* the actual length of the encapsulated command (which is not in the v1
+ * header)
+ */
#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_LBN 16
#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_WIDTH 10
#define MC_CMD_V2_EXTN_IN_UNUSED2_LBN 26
@@ -5035,25 +9619,35 @@
/***********************************/
-/* MC_CMD_TCM_BUCKET_ALLOC
+/* MC_CMD_TCM_BUCKET_ALLOC
+ * Allocate a pacer bucket (for qau rp or a snapper test)
*/
-#define MC_CMD_TCM_BUCKET_ALLOC 0x80
+#define MC_CMD_TCM_BUCKET_ALLOC 0xb2
+#undef MC_CMD_0xb2_PRIVILEGE_CTG
+
+#define MC_CMD_0xb2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_TCM_BUCKET_ALLOC_IN msgrequest */
#define MC_CMD_TCM_BUCKET_ALLOC_IN_LEN 0
/* MC_CMD_TCM_BUCKET_ALLOC_OUT msgresponse */
#define MC_CMD_TCM_BUCKET_ALLOC_OUT_LEN 4
+/* the bucket id */
#define MC_CMD_TCM_BUCKET_ALLOC_OUT_BUCKET_OFST 0
/***********************************/
-/* MC_CMD_TCM_BUCKET_FREE
+/* MC_CMD_TCM_BUCKET_FREE
+ * Free a pacer bucket
*/
-#define MC_CMD_TCM_BUCKET_FREE 0x81
+#define MC_CMD_TCM_BUCKET_FREE 0xb3
+#undef MC_CMD_0xb3_PRIVILEGE_CTG
+
+#define MC_CMD_0xb3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_TCM_BUCKET_FREE_IN msgrequest */
#define MC_CMD_TCM_BUCKET_FREE_IN_LEN 4
+/* the bucket id */
#define MC_CMD_TCM_BUCKET_FREE_IN_BUCKET_OFST 0
/* MC_CMD_TCM_BUCKET_FREE_OUT msgresponse */
@@ -5061,35 +9655,2865 @@
/***********************************/
-/* MC_CMD_TCM_BUCKET_INIT
+/* MC_CMD_TCM_BUCKET_INIT
+ * Initialise pacer bucket with a given rate
*/
-#define MC_CMD_TCM_BUCKET_INIT 0x82
+#define MC_CMD_TCM_BUCKET_INIT 0xb4
+#undef MC_CMD_0xb4_PRIVILEGE_CTG
+
+#define MC_CMD_0xb4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_TCM_BUCKET_INIT_IN msgrequest */
#define MC_CMD_TCM_BUCKET_INIT_IN_LEN 8
+/* the bucket id */
#define MC_CMD_TCM_BUCKET_INIT_IN_BUCKET_OFST 0
+/* the rate in mbps */
#define MC_CMD_TCM_BUCKET_INIT_IN_RATE_OFST 4
+/* MC_CMD_TCM_BUCKET_INIT_EXT_IN msgrequest */
+#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_LEN 12
+/* the bucket id */
+#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_BUCKET_OFST 0
+/* the rate in mbps */
+#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_RATE_OFST 4
+/* the desired maximum fill level */
+#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_MAX_FILL_OFST 8
+
/* MC_CMD_TCM_BUCKET_INIT_OUT msgresponse */
#define MC_CMD_TCM_BUCKET_INIT_OUT_LEN 0
/***********************************/
-/* MC_CMD_TCM_TXQ_INIT
+/* MC_CMD_TCM_TXQ_INIT
+ * Initialise txq in pacer with given options or set options
*/
-#define MC_CMD_TCM_TXQ_INIT 0x83
+#define MC_CMD_TCM_TXQ_INIT 0xb5
+#undef MC_CMD_0xb5_PRIVILEGE_CTG
+
+#define MC_CMD_0xb5_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_TCM_TXQ_INIT_IN msgrequest */
#define MC_CMD_TCM_TXQ_INIT_IN_LEN 28
+/* the txq id */
#define MC_CMD_TCM_TXQ_INIT_IN_QID_OFST 0
+/* the static priority associated with the txq */
#define MC_CMD_TCM_TXQ_INIT_IN_LABEL_OFST 4
+/* bitmask of the priority queues this txq is inserted into when inserted. */
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAGS_OFST 8
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_LBN 0
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_NORMAL_LBN 1
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_NORMAL_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_LOW_LBN 2
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_LOW_WIDTH 1
+/* the reaction point (RP) bucket */
#define MC_CMD_TCM_TXQ_INIT_IN_RP_BKT_OFST 12
+/* an already reserved bucket (typically set to bucket associated with outer
+ * vswitch)
+ */
#define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT1_OFST 16
+/* an already reserved bucket (typically set to bucket associated with inner
+ * vswitch)
+ */
#define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT2_OFST 20
+/* the min bucket (typically for ETS/minimum bandwidth) */
#define MC_CMD_TCM_TXQ_INIT_IN_MIN_BKT_OFST 24
+/* MC_CMD_TCM_TXQ_INIT_EXT_IN msgrequest */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_LEN 32
+/* the txq id */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_QID_OFST 0
+/* the static priority associated with the txq */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_LABEL_NORMAL_OFST 4
+/* bitmask of the priority queues this txq is inserted into when inserted. */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAGS_OFST 8
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_LBN 0
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_NORMAL_LBN 1
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_NORMAL_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_LOW_LBN 2
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_LOW_WIDTH 1
+/* the reaction point (RP) bucket */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_RP_BKT_OFST 12
+/* an already reserved bucket (typically set to bucket associated with outer
+ * vswitch)
+ */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MAX_BKT1_OFST 16
+/* an already reserved bucket (typically set to bucket associated with inner
+ * vswitch)
+ */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MAX_BKT2_OFST 20
+/* the min bucket (typically for ETS/minimum bandwidth) */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MIN_BKT_OFST 24
+/* the static priority associated with the txq */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_LABEL_GUARANTEED_OFST 28
+
/* MC_CMD_TCM_TXQ_INIT_OUT msgresponse */
#define MC_CMD_TCM_TXQ_INIT_OUT_LEN 0
+
+/***********************************/
+/* MC_CMD_LINK_PIOBUF
+ * Link a push I/O buffer to a TxQ
+ */
+#define MC_CMD_LINK_PIOBUF 0x92
+#undef MC_CMD_0x92_PRIVILEGE_CTG
+
+#define MC_CMD_0x92_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
+
+/* MC_CMD_LINK_PIOBUF_IN msgrequest */
+#define MC_CMD_LINK_PIOBUF_IN_LEN 8
+/* Handle for allocated push I/O buffer. */
+#define MC_CMD_LINK_PIOBUF_IN_PIOBUF_HANDLE_OFST 0
+/* Function Local Instance (VI) number. */
+#define MC_CMD_LINK_PIOBUF_IN_TXQ_INSTANCE_OFST 4
+
+/* MC_CMD_LINK_PIOBUF_OUT msgresponse */
+#define MC_CMD_LINK_PIOBUF_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_UNLINK_PIOBUF
+ * Unlink a push I/O buffer from a TxQ
+ */
+#define MC_CMD_UNLINK_PIOBUF 0x93
+#undef MC_CMD_0x93_PRIVILEGE_CTG
+
+#define MC_CMD_0x93_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
+
+/* MC_CMD_UNLINK_PIOBUF_IN msgrequest */
+#define MC_CMD_UNLINK_PIOBUF_IN_LEN 4
+/* Function Local Instance (VI) number. */
+#define MC_CMD_UNLINK_PIOBUF_IN_TXQ_INSTANCE_OFST 0
+
+/* MC_CMD_UNLINK_PIOBUF_OUT msgresponse */
+#define MC_CMD_UNLINK_PIOBUF_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VSWITCH_ALLOC
+ * allocate and initialise a v-switch.
+ */
+#define MC_CMD_VSWITCH_ALLOC 0x94
+#undef MC_CMD_0x94_PRIVILEGE_CTG
+
+#define MC_CMD_0x94_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VSWITCH_ALLOC_IN msgrequest */
+#define MC_CMD_VSWITCH_ALLOC_IN_LEN 16
+/* The port to connect to the v-switch's upstream port. */
+#define MC_CMD_VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* The type of v-switch to create. */
+#define MC_CMD_VSWITCH_ALLOC_IN_TYPE_OFST 4
+/* enum: VLAN */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN 0x1
+/* enum: VEB */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB 0x2
+/* enum: VEPA (obsolete) */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEPA 0x3
+/* enum: MUX */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_MUX 0x4
+/* enum: Snapper specific; semantics TBD */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_TEST 0x5
+/* Flags controlling v-port creation */
+#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_OFST 8
+#define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_LBN 0
+#define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_WIDTH 1
+/* The number of VLAN tags to allow for attached v-ports. For VLAN aggregators,
+ * this must be one or greated, and the attached v-ports must have exactly this
+ * number of tags. For other v-switch types, this must be zero of greater, and
+ * is an upper limit on the number of VLAN tags for attached v-ports. An error
+ * will be returned if existing configuration means we can't support attached
+ * v-ports with this number of tags.
+ */
+#define MC_CMD_VSWITCH_ALLOC_IN_NUM_VLAN_TAGS_OFST 12
+
+/* MC_CMD_VSWITCH_ALLOC_OUT msgresponse */
+#define MC_CMD_VSWITCH_ALLOC_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VSWITCH_FREE
+ * de-allocate a v-switch.
+ */
+#define MC_CMD_VSWITCH_FREE 0x95
+#undef MC_CMD_0x95_PRIVILEGE_CTG
+
+#define MC_CMD_0x95_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VSWITCH_FREE_IN msgrequest */
+#define MC_CMD_VSWITCH_FREE_IN_LEN 4
+/* The port to which the v-switch is connected. */
+#define MC_CMD_VSWITCH_FREE_IN_UPSTREAM_PORT_ID_OFST 0
+
+/* MC_CMD_VSWITCH_FREE_OUT msgresponse */
+#define MC_CMD_VSWITCH_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_ALLOC
+ * allocate a v-port.
+ */
+#define MC_CMD_VPORT_ALLOC 0x96
+#undef MC_CMD_0x96_PRIVILEGE_CTG
+
+#define MC_CMD_0x96_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_ALLOC_IN msgrequest */
+#define MC_CMD_VPORT_ALLOC_IN_LEN 20
+/* The port to which the v-switch is connected. */
+#define MC_CMD_VPORT_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* The type of the new v-port. */
+#define MC_CMD_VPORT_ALLOC_IN_TYPE_OFST 4
+/* enum: VLAN (obsolete) */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VLAN 0x1
+/* enum: VEB (obsolete) */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VEB 0x2
+/* enum: VEPA (obsolete) */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VEPA 0x3
+/* enum: A normal v-port receives packets which match a specified MAC and/or
+ * VLAN.
+ */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL 0x4
+/* enum: An expansion v-port packets traffic which don't match any other
+ * v-port.
+ */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_EXPANSION 0x5
+/* enum: An test v-port receives packets which match any filters installed by
+ * its downstream components.
+ */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST 0x6
+/* Flags controlling v-port creation */
+#define MC_CMD_VPORT_ALLOC_IN_FLAGS_OFST 8
+#define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_LBN 0
+#define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_WIDTH 1
+/* The number of VLAN tags to insert/remove. An error will be returned if
+ * incompatible with the number of VLAN tags specified for the upstream
+ * v-switch.
+ */
+#define MC_CMD_VPORT_ALLOC_IN_NUM_VLAN_TAGS_OFST 12
+/* The actual VLAN tags to insert/remove */
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAGS_OFST 16
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_LBN 0
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_WIDTH 16
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_1_LBN 16
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_1_WIDTH 16
+
+/* MC_CMD_VPORT_ALLOC_OUT msgresponse */
+#define MC_CMD_VPORT_ALLOC_OUT_LEN 4
+/* The handle of the new v-port */
+#define MC_CMD_VPORT_ALLOC_OUT_VPORT_ID_OFST 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_FREE
+ * de-allocate a v-port.
+ */
+#define MC_CMD_VPORT_FREE 0x97
+#undef MC_CMD_0x97_PRIVILEGE_CTG
+
+#define MC_CMD_0x97_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_FREE_IN msgrequest */
+#define MC_CMD_VPORT_FREE_IN_LEN 4
+/* The handle of the v-port */
+#define MC_CMD_VPORT_FREE_IN_VPORT_ID_OFST 0
+
+/* MC_CMD_VPORT_FREE_OUT msgresponse */
+#define MC_CMD_VPORT_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VADAPTOR_ALLOC
+ * allocate a v-adaptor.
+ */
+#define MC_CMD_VADAPTOR_ALLOC 0x98
+#undef MC_CMD_0x98_PRIVILEGE_CTG
+
+#define MC_CMD_0x98_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VADAPTOR_ALLOC_IN msgrequest */
+#define MC_CMD_VADAPTOR_ALLOC_IN_LEN 30
+/* The port to connect to the v-adaptor's port. */
+#define MC_CMD_VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* Flags controlling v-adaptor creation */
+#define MC_CMD_VADAPTOR_ALLOC_IN_FLAGS_OFST 8
+#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_LBN 0
+#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_WIDTH 1
+/* The number of VLAN tags to strip on receive */
+#define MC_CMD_VADAPTOR_ALLOC_IN_NUM_VLANS_OFST 12
+/* The number of VLAN tags to transparently insert/remove. */
+#define MC_CMD_VADAPTOR_ALLOC_IN_NUM_VLAN_TAGS_OFST 16
+/* The actual VLAN tags to insert/remove */
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAGS_OFST 20
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_LBN 0
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_WIDTH 16
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_1_LBN 16
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_1_WIDTH 16
+/* The MAC address to assign to this v-adaptor */
+#define MC_CMD_VADAPTOR_ALLOC_IN_MACADDR_OFST 24
+#define MC_CMD_VADAPTOR_ALLOC_IN_MACADDR_LEN 6
+/* enum: Derive the MAC address from the upstream port */
+#define MC_CMD_VADAPTOR_ALLOC_IN_AUTO_MAC 0x0
+
+/* MC_CMD_VADAPTOR_ALLOC_OUT msgresponse */
+#define MC_CMD_VADAPTOR_ALLOC_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VADAPTOR_FREE
+ * de-allocate a v-adaptor.
+ */
+#define MC_CMD_VADAPTOR_FREE 0x99
+#undef MC_CMD_0x99_PRIVILEGE_CTG
+
+#define MC_CMD_0x99_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VADAPTOR_FREE_IN msgrequest */
+#define MC_CMD_VADAPTOR_FREE_IN_LEN 4
+/* The port to which the v-adaptor is connected. */
+#define MC_CMD_VADAPTOR_FREE_IN_UPSTREAM_PORT_ID_OFST 0
+
+/* MC_CMD_VADAPTOR_FREE_OUT msgresponse */
+#define MC_CMD_VADAPTOR_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VADAPTOR_SET_MAC
+ * assign a new MAC address to a v-adaptor.
+ */
+#define MC_CMD_VADAPTOR_SET_MAC 0x5d
+#undef MC_CMD_0x5d_PRIVILEGE_CTG
+
+#define MC_CMD_0x5d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VADAPTOR_SET_MAC_IN msgrequest */
+#define MC_CMD_VADAPTOR_SET_MAC_IN_LEN 10
+/* The port to which the v-adaptor is connected. */
+#define MC_CMD_VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID_OFST 0
+/* The new MAC address to assign to this v-adaptor */
+#define MC_CMD_VADAPTOR_SET_MAC_IN_MACADDR_OFST 4
+#define MC_CMD_VADAPTOR_SET_MAC_IN_MACADDR_LEN 6
+
+/* MC_CMD_VADAPTOR_SET_MAC_OUT msgresponse */
+#define MC_CMD_VADAPTOR_SET_MAC_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VADAPTOR_GET_MAC
+ * read the MAC address assigned to a v-adaptor.
+ */
+#define MC_CMD_VADAPTOR_GET_MAC 0x5e
+#undef MC_CMD_0x5e_PRIVILEGE_CTG
+
+#define MC_CMD_0x5e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VADAPTOR_GET_MAC_IN msgrequest */
+#define MC_CMD_VADAPTOR_GET_MAC_IN_LEN 4
+/* The port to which the v-adaptor is connected. */
+#define MC_CMD_VADAPTOR_GET_MAC_IN_UPSTREAM_PORT_ID_OFST 0
+
+/* MC_CMD_VADAPTOR_GET_MAC_OUT msgresponse */
+#define MC_CMD_VADAPTOR_GET_MAC_OUT_LEN 6
+/* The MAC address assigned to this v-adaptor */
+#define MC_CMD_VADAPTOR_GET_MAC_OUT_MACADDR_OFST 0
+#define MC_CMD_VADAPTOR_GET_MAC_OUT_MACADDR_LEN 6
+
+
+/***********************************/
+/* MC_CMD_EVB_PORT_ASSIGN
+ * assign a port to a PCI function.
+ */
+#define MC_CMD_EVB_PORT_ASSIGN 0x9a
+#undef MC_CMD_0x9a_PRIVILEGE_CTG
+
+#define MC_CMD_0x9a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_EVB_PORT_ASSIGN_IN msgrequest */
+#define MC_CMD_EVB_PORT_ASSIGN_IN_LEN 8
+/* The port to assign. */
+#define MC_CMD_EVB_PORT_ASSIGN_IN_PORT_ID_OFST 0
+/* The target function to modify. */
+#define MC_CMD_EVB_PORT_ASSIGN_IN_FUNCTION_OFST 4
+#define MC_CMD_EVB_PORT_ASSIGN_IN_PF_LBN 0
+#define MC_CMD_EVB_PORT_ASSIGN_IN_PF_WIDTH 16
+#define MC_CMD_EVB_PORT_ASSIGN_IN_VF_LBN 16
+#define MC_CMD_EVB_PORT_ASSIGN_IN_VF_WIDTH 16
+
+/* MC_CMD_EVB_PORT_ASSIGN_OUT msgresponse */
+#define MC_CMD_EVB_PORT_ASSIGN_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RDWR_A64_REGIONS
+ * Assign the 64 bit region addresses.
+ */
+#define MC_CMD_RDWR_A64_REGIONS 0x9b
+#undef MC_CMD_0x9b_PRIVILEGE_CTG
+
+#define MC_CMD_0x9b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_RDWR_A64_REGIONS_IN msgrequest */
+#define MC_CMD_RDWR_A64_REGIONS_IN_LEN 17
+#define MC_CMD_RDWR_A64_REGIONS_IN_REGION0_OFST 0
+#define MC_CMD_RDWR_A64_REGIONS_IN_REGION1_OFST 4
+#define MC_CMD_RDWR_A64_REGIONS_IN_REGION2_OFST 8
+#define MC_CMD_RDWR_A64_REGIONS_IN_REGION3_OFST 12
+/* Write enable bits 0-3, set to write, clear to read. */
+#define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_LBN 128
+#define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_WIDTH 4
+#define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_BYTE_OFST 16
+#define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_BYTE_LEN 1
+
+/* MC_CMD_RDWR_A64_REGIONS_OUT msgresponse: This data always included
+ * regardless of state of write bits in the request.
+ */
+#define MC_CMD_RDWR_A64_REGIONS_OUT_LEN 16
+#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION0_OFST 0
+#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION1_OFST 4
+#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION2_OFST 8
+#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION3_OFST 12
+
+
+/***********************************/
+/* MC_CMD_ONLOAD_STACK_ALLOC
+ * Allocate an Onload stack ID.
+ */
+#define MC_CMD_ONLOAD_STACK_ALLOC 0x9c
+#undef MC_CMD_0x9c_PRIVILEGE_CTG
+
+#define MC_CMD_0x9c_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
+
+/* MC_CMD_ONLOAD_STACK_ALLOC_IN msgrequest */
+#define MC_CMD_ONLOAD_STACK_ALLOC_IN_LEN 4
+/* The handle of the owning upstream port */
+#define MC_CMD_ONLOAD_STACK_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+
+/* MC_CMD_ONLOAD_STACK_ALLOC_OUT msgresponse */
+#define MC_CMD_ONLOAD_STACK_ALLOC_OUT_LEN 4
+/* The handle of the new Onload stack */
+#define MC_CMD_ONLOAD_STACK_ALLOC_OUT_ONLOAD_STACK_ID_OFST 0
+
+
+/***********************************/
+/* MC_CMD_ONLOAD_STACK_FREE
+ * Free an Onload stack ID.
+ */
+#define MC_CMD_ONLOAD_STACK_FREE 0x9d
+#undef MC_CMD_0x9d_PRIVILEGE_CTG
+
+#define MC_CMD_0x9d_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
+
+/* MC_CMD_ONLOAD_STACK_FREE_IN msgrequest */
+#define MC_CMD_ONLOAD_STACK_FREE_IN_LEN 4
+/* The handle of the Onload stack */
+#define MC_CMD_ONLOAD_STACK_FREE_IN_ONLOAD_STACK_ID_OFST 0
+
+/* MC_CMD_ONLOAD_STACK_FREE_OUT msgresponse */
+#define MC_CMD_ONLOAD_STACK_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_ALLOC
+ * Allocate an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC 0x9e
+#undef MC_CMD_0x9e_PRIVILEGE_CTG
+
+#define MC_CMD_0x9e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_ALLOC_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN 12
+/* The handle of the owning upstream port */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* The type of context to allocate */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_OFST 4
+/* enum: Allocate a context for exclusive use. The key and indirection table
+ * must be explicitly configured.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE 0x0
+/* enum: Allocate a context for shared use; this will spread across a range of
+ * queues, but the key and indirection table are pre-configured and may not be
+ * changed. For this mode, NUM_QUEUES must 2, 4, 8, 16, 32 or 64.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED 0x1
+/* Number of queues spanned by this context, in the range 1-64; valid offsets
+ * in the indirection table will be in the range 0 to NUM_QUEUES-1.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_NUM_QUEUES_OFST 8
+
+/* MC_CMD_RSS_CONTEXT_ALLOC_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN 4
+/* The handle of the new RSS context. This should be considered opaque to the
+ * host, although a value of 0xFFFFFFFF is guaranteed never to be a valid
+ * handle.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_OFST 0
+/* enum: guaranteed invalid RSS context handle value */
+#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_INVALID 0xffffffff
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_FREE
+ * Free an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_FREE 0x9f
+#undef MC_CMD_0x9f_PRIVILEGE_CTG
+
+#define MC_CMD_0x9f_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_FREE_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_FREE_IN_LEN 4
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID_OFST 0
+
+/* MC_CMD_RSS_CONTEXT_FREE_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_SET_KEY
+ * Set the Toeplitz hash key for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_SET_KEY 0xa0
+#undef MC_CMD_0xa0_PRIVILEGE_CTG
+
+#define MC_CMD_0xa0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_SET_KEY_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN 44
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID_OFST 0
+/* The 40-byte Toeplitz hash key (TBD endianness issues?) */
+#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_OFST 4
+#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN 40
+
+/* MC_CMD_RSS_CONTEXT_SET_KEY_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_GET_KEY
+ * Get the Toeplitz hash key for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_GET_KEY 0xa1
+#undef MC_CMD_0xa1_PRIVILEGE_CTG
+
+#define MC_CMD_0xa1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_GET_KEY_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_GET_KEY_IN_LEN 4
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_GET_KEY_IN_RSS_CONTEXT_ID_OFST 0
+
+/* MC_CMD_RSS_CONTEXT_GET_KEY_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN 44
+/* The 40-byte Toeplitz hash key (TBD endianness issues?) */
+#define MC_CMD_RSS_CONTEXT_GET_KEY_OUT_TOEPLITZ_KEY_OFST 4
+#define MC_CMD_RSS_CONTEXT_GET_KEY_OUT_TOEPLITZ_KEY_LEN 40
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_SET_TABLE
+ * Set the indirection table for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE 0xa2
+#undef MC_CMD_0xa2_PRIVILEGE_CTG
+
+#define MC_CMD_0xa2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_SET_TABLE_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN 132
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID_OFST 0
+/* The 128-byte indirection table (1 byte per entry) */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_OFST 4
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN 128
+
+/* MC_CMD_RSS_CONTEXT_SET_TABLE_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_GET_TABLE
+ * Get the indirection table for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE 0xa3
+#undef MC_CMD_0xa3_PRIVILEGE_CTG
+
+#define MC_CMD_0xa3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_GET_TABLE_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN 4
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_IN_RSS_CONTEXT_ID_OFST 0
+
+/* MC_CMD_RSS_CONTEXT_GET_TABLE_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN 132
+/* The 128-byte indirection table (1 byte per entry) */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE_OFST 4
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE_LEN 128
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_SET_FLAGS
+ * Set various control flags for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS 0xe1
+#undef MC_CMD_0xe1_PRIVILEGE_CTG
+
+#define MC_CMD_0xe1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_SET_FLAGS_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN 8
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID_OFST 0
+/* Hash control flags. The _EN bits are always supported. The _MODE bits only
+ * work when the firmware reports ADDITIONAL_RSS_MODES in
+ * MC_CMD_GET_CAPABILITIES and override the _EN bits if any of them are not 0.
+ * See the RSS_MODE structure for the meaning of the mode bits.
+ */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_FLAGS_OFST 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_LBN 0
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN_LBN 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN_LBN 2
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN_LBN 3
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RESERVED_LBN 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RESERVED_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_LBN 8
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE_LBN 12
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_LBN 16
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_LBN 20
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE_LBN 24
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_LBN 28
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_WIDTH 4
+
+/* MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_GET_FLAGS
+ * Get various control flags for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS 0xe2
+#undef MC_CMD_0xe2_PRIVILEGE_CTG
+
+#define MC_CMD_0xe2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_GET_FLAGS_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_LEN 4
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_RSS_CONTEXT_ID_OFST 0
+
+/* MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN 8
+/* Hash control flags. If any _MODE bits are non-zero (which will only be true
+ * when the firmware reports ADDITIONAL_RSS_MODES) then the _EN bits should be
+ * disregarded (but are guaranteed to be consistent with the _MODE bits if
+ * RSS_CONTEXT_SET_FLAGS has never been called for this context since it was
+ * allocated).
+ */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_FLAGS_OFST 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_LBN 0
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_LBN 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_LBN 2
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_LBN 3
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_RESERVED_LBN 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_RESERVED_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_LBN 8
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN 12
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_LBN 16
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_LBN 20
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN 24
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_LBN 28
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_WIDTH 4
+
+
+/***********************************/
+/* MC_CMD_DOT1P_MAPPING_ALLOC
+ * Allocate a .1p mapping.
+ */
+#define MC_CMD_DOT1P_MAPPING_ALLOC 0xa4
+#undef MC_CMD_0xa4_PRIVILEGE_CTG
+
+#define MC_CMD_0xa4_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DOT1P_MAPPING_ALLOC_IN msgrequest */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_IN_LEN 8
+/* The handle of the owning upstream port */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* Number of queues spanned by this mapping, in the range 1-64; valid fixed
+ * offsets in the mapping table will be in the range 0 to NUM_QUEUES-1, and
+ * referenced RSS contexts must span no more than this number.
+ */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_IN_NUM_QUEUES_OFST 4
+
+/* MC_CMD_DOT1P_MAPPING_ALLOC_OUT msgresponse */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_LEN 4
+/* The handle of the new .1p mapping. This should be considered opaque to the
+ * host, although a value of 0xFFFFFFFF is guaranteed never to be a valid
+ * handle.
+ */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_OFST 0
+/* enum: guaranteed invalid .1p mapping handle value */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_INVALID 0xffffffff
+
+
+/***********************************/
+/* MC_CMD_DOT1P_MAPPING_FREE
+ * Free a .1p mapping.
+ */
+#define MC_CMD_DOT1P_MAPPING_FREE 0xa5
+#undef MC_CMD_0xa5_PRIVILEGE_CTG
+
+#define MC_CMD_0xa5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DOT1P_MAPPING_FREE_IN msgrequest */
+#define MC_CMD_DOT1P_MAPPING_FREE_IN_LEN 4
+/* The handle of the .1p mapping */
+#define MC_CMD_DOT1P_MAPPING_FREE_IN_DOT1P_MAPPING_ID_OFST 0
+
+/* MC_CMD_DOT1P_MAPPING_FREE_OUT msgresponse */
+#define MC_CMD_DOT1P_MAPPING_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_DOT1P_MAPPING_SET_TABLE
+ * Set the mapping table for a .1p mapping.
+ */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE 0xa6
+#undef MC_CMD_0xa6_PRIVILEGE_CTG
+
+#define MC_CMD_0xa6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DOT1P_MAPPING_SET_TABLE_IN msgrequest */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_LEN 36
+/* The handle of the .1p mapping */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_DOT1P_MAPPING_ID_OFST 0
+/* Per-priority mappings (1 32-bit word per entry - an offset or RSS context
+ * handle)
+ */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_MAPPING_TABLE_OFST 4
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_MAPPING_TABLE_LEN 32
+
+/* MC_CMD_DOT1P_MAPPING_SET_TABLE_OUT msgresponse */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_DOT1P_MAPPING_GET_TABLE
+ * Get the mapping table for a .1p mapping.
+ */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE 0xa7
+#undef MC_CMD_0xa7_PRIVILEGE_CTG
+
+#define MC_CMD_0xa7_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DOT1P_MAPPING_GET_TABLE_IN msgrequest */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_IN_LEN 4
+/* The handle of the .1p mapping */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_IN_DOT1P_MAPPING_ID_OFST 0
+
+/* MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT msgresponse */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT_LEN 36
+/* Per-priority mappings (1 32-bit word per entry - an offset or RSS context
+ * handle)
+ */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT_MAPPING_TABLE_OFST 4
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT_MAPPING_TABLE_LEN 32
+
+
+/***********************************/
+/* MC_CMD_GET_VECTOR_CFG
+ * Get Interrupt Vector config for this PF.
+ */
+#define MC_CMD_GET_VECTOR_CFG 0xbf
+#undef MC_CMD_0xbf_PRIVILEGE_CTG
+
+#define MC_CMD_0xbf_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_VECTOR_CFG_IN msgrequest */
+#define MC_CMD_GET_VECTOR_CFG_IN_LEN 0
+
+/* MC_CMD_GET_VECTOR_CFG_OUT msgresponse */
+#define MC_CMD_GET_VECTOR_CFG_OUT_LEN 12
+/* Base absolute interrupt vector number. */
+#define MC_CMD_GET_VECTOR_CFG_OUT_VEC_BASE_OFST 0
+/* Number of interrupt vectors allocate to this PF. */
+#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_PF_OFST 4
+/* Number of interrupt vectors to allocate per VF. */
+#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_VF_OFST 8
+
+
+/***********************************/
+/* MC_CMD_SET_VECTOR_CFG
+ * Set Interrupt Vector config for this PF.
+ */
+#define MC_CMD_SET_VECTOR_CFG 0xc0
+#undef MC_CMD_0xc0_PRIVILEGE_CTG
+
+#define MC_CMD_0xc0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_SET_VECTOR_CFG_IN msgrequest */
+#define MC_CMD_SET_VECTOR_CFG_IN_LEN 12
+/* Base absolute interrupt vector number, or MC_CMD_RESOURCE_INSTANCE_ANY to
+ * let the system find a suitable base.
+ */
+#define MC_CMD_SET_VECTOR_CFG_IN_VEC_BASE_OFST 0
+/* Number of interrupt vectors allocate to this PF. */
+#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_PF_OFST 4
+/* Number of interrupt vectors to allocate per VF. */
+#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_VF_OFST 8
+
+/* MC_CMD_SET_VECTOR_CFG_OUT msgresponse */
+#define MC_CMD_SET_VECTOR_CFG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_ADD_MAC_ADDRESS
+ * Add a MAC address to a v-port
+ */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS 0xa8
+#undef MC_CMD_0xa8_PRIVILEGE_CTG
+
+#define MC_CMD_0xa8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_ADD_MAC_ADDRESS_IN msgrequest */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN 10
+/* The handle of the v-port */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID_OFST 0
+/* MAC address to add */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_MACADDR_OFST 4
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_MACADDR_LEN 6
+
+/* MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT msgresponse */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_DEL_MAC_ADDRESS
+ * Delete a MAC address from a v-port
+ */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS 0xa9
+#undef MC_CMD_0xa9_PRIVILEGE_CTG
+
+#define MC_CMD_0xa9_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_DEL_MAC_ADDRESS_IN msgrequest */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN 10
+/* The handle of the v-port */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID_OFST 0
+/* MAC address to add */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_MACADDR_OFST 4
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_MACADDR_LEN 6
+
+/* MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT msgresponse */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_GET_MAC_ADDRESSES
+ * Delete a MAC address from a v-port
+ */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES 0xaa
+#undef MC_CMD_0xaa_PRIVILEGE_CTG
+
+#define MC_CMD_0xaa_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_GET_MAC_ADDRESSES_IN msgrequest */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN 4
+/* The handle of the v-port */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID_OFST 0
+
+/* MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT msgresponse */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN 4
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX 250
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LEN(num) (4+6*(num))
+/* The number of MAC addresses returned */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT_OFST 0
+/* Array of MAC addresses */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_OFST 4
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_LEN 6
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_MINNUM 0
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_MAXNUM 41
+
+
+/***********************************/
+/* MC_CMD_DUMP_BUFTBL_ENTRIES
+ * Dump buffer table entries, mainly for command client debug use. Dumps
+ * absolute entries, and does not use chunk handles. All entries must be in
+ * range, and used for q page mapping, Although the latter restriction may be
+ * lifted in future.
+ */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES 0xab
+#undef MC_CMD_0xab_PRIVILEGE_CTG
+
+#define MC_CMD_0xab_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DUMP_BUFTBL_ENTRIES_IN msgrequest */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_LEN 8
+/* Index of the first buffer table entry. */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_FIRSTID_OFST 0
+/* Number of buffer table entries to dump. */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_NUMENTRIES_OFST 4
+
+/* MC_CMD_DUMP_BUFTBL_ENTRIES_OUT msgresponse */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMIN 12
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMAX 252
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LEN(num) (0+12*(num))
+/* Raw buffer table entries, layed out as BUFTBL_ENTRY. */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_OFST 0
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_LEN 12
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MINNUM 1
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MAXNUM 21
+
+
+/***********************************/
+/* MC_CMD_SET_RXDP_CONFIG
+ * Set global RXDP configuration settings
+ */
+#define MC_CMD_SET_RXDP_CONFIG 0xc1
+#undef MC_CMD_0xc1_PRIVILEGE_CTG
+
+#define MC_CMD_0xc1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_RXDP_CONFIG_IN msgrequest */
+#define MC_CMD_SET_RXDP_CONFIG_IN_LEN 4
+#define MC_CMD_SET_RXDP_CONFIG_IN_DATA_OFST 0
+#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_LBN 0
+#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_WIDTH 1
+
+/* MC_CMD_SET_RXDP_CONFIG_OUT msgresponse */
+#define MC_CMD_SET_RXDP_CONFIG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_RXDP_CONFIG
+ * Get global RXDP configuration settings
+ */
+#define MC_CMD_GET_RXDP_CONFIG 0xc2
+#undef MC_CMD_0xc2_PRIVILEGE_CTG
+
+#define MC_CMD_0xc2_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_RXDP_CONFIG_IN msgrequest */
+#define MC_CMD_GET_RXDP_CONFIG_IN_LEN 0
+
+/* MC_CMD_GET_RXDP_CONFIG_OUT msgresponse */
+#define MC_CMD_GET_RXDP_CONFIG_OUT_LEN 4
+#define MC_CMD_GET_RXDP_CONFIG_OUT_DATA_OFST 0
+#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_LBN 0
+#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_WIDTH 1
+
+
+/***********************************/
+/* MC_CMD_GET_CLOCK
+ * Return the system and PDCPU clock frequencies.
+ */
+#define MC_CMD_GET_CLOCK 0xac
+#undef MC_CMD_0xac_PRIVILEGE_CTG
+
+#define MC_CMD_0xac_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_CLOCK_IN msgrequest */
+#define MC_CMD_GET_CLOCK_IN_LEN 0
+
+/* MC_CMD_GET_CLOCK_OUT msgresponse */
+#define MC_CMD_GET_CLOCK_OUT_LEN 8
+/* System frequency, MHz */
+#define MC_CMD_GET_CLOCK_OUT_SYS_FREQ_OFST 0
+/* DPCPU frequency, MHz */
+#define MC_CMD_GET_CLOCK_OUT_DPCPU_FREQ_OFST 4
+
+
+/***********************************/
+/* MC_CMD_SET_CLOCK
+ * Control the system and DPCPU clock frequencies. Changes are lost reboot.
+ */
+#define MC_CMD_SET_CLOCK 0xad
+#undef MC_CMD_0xad_PRIVILEGE_CTG
+
+#define MC_CMD_0xad_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_CLOCK_IN msgrequest */
+#define MC_CMD_SET_CLOCK_IN_LEN 28
+/* Requested frequency in MHz for system clock domain */
+#define MC_CMD_SET_CLOCK_IN_SYS_FREQ_OFST 0
+/* enum: Leave the system clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_SYS_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for inter-core clock domain */
+#define MC_CMD_SET_CLOCK_IN_ICORE_FREQ_OFST 4
+/* enum: Leave the inter-core clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_ICORE_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for DPCPU clock domain */
+#define MC_CMD_SET_CLOCK_IN_DPCPU_FREQ_OFST 8
+/* enum: Leave the DPCPU clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_DPCPU_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for PCS clock domain */
+#define MC_CMD_SET_CLOCK_IN_PCS_FREQ_OFST 12
+/* enum: Leave the PCS clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_PCS_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for MC clock domain */
+#define MC_CMD_SET_CLOCK_IN_MC_FREQ_OFST 16
+/* enum: Leave the MC clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_MC_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for rmon clock domain */
+#define MC_CMD_SET_CLOCK_IN_RMON_FREQ_OFST 20
+/* enum: Leave the rmon clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_RMON_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for vswitch clock domain */
+#define MC_CMD_SET_CLOCK_IN_VSWITCH_FREQ_OFST 24
+/* enum: Leave the vswitch clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_VSWITCH_DOMAIN_DONT_CHANGE 0x0
+
+/* MC_CMD_SET_CLOCK_OUT msgresponse */
+#define MC_CMD_SET_CLOCK_OUT_LEN 28
+/* Resulting system frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_SYS_FREQ_OFST 0
+/* enum: The system clock domain doesn't exist */
+#define MC_CMD_SET_CLOCK_OUT_SYS_DOMAIN_UNSUPPORTED 0x0
+/* Resulting inter-core frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_ICORE_FREQ_OFST 4
+/* enum: The inter-core clock domain doesn't exist / isn't used */
+#define MC_CMD_SET_CLOCK_OUT_ICORE_DOMAIN_UNSUPPORTED 0x0
+/* Resulting DPCPU frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_DPCPU_FREQ_OFST 8
+/* enum: The dpcpu clock domain doesn't exist */
+#define MC_CMD_SET_CLOCK_OUT_DPCPU_DOMAIN_UNSUPPORTED 0x0
+/* Resulting PCS frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_PCS_FREQ_OFST 12
+/* enum: The PCS clock domain doesn't exist / isn't controlled */
+#define MC_CMD_SET_CLOCK_OUT_PCS_DOMAIN_UNSUPPORTED 0x0
+/* Resulting MC frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_MC_FREQ_OFST 16
+/* enum: The MC clock domain doesn't exist / isn't controlled */
+#define MC_CMD_SET_CLOCK_OUT_MC_DOMAIN_UNSUPPORTED 0x0
+/* Resulting rmon frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_RMON_FREQ_OFST 20
+/* enum: The rmon clock domain doesn't exist / isn't controlled */
+#define MC_CMD_SET_CLOCK_OUT_RMON_DOMAIN_UNSUPPORTED 0x0
+/* Resulting vswitch frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_VSWITCH_FREQ_OFST 24
+/* enum: The vswitch clock domain doesn't exist / isn't controlled */
+#define MC_CMD_SET_CLOCK_OUT_VSWITCH_DOMAIN_UNSUPPORTED 0x0
+
+
+/***********************************/
+/* MC_CMD_DPCPU_RPC
+ * Send an arbitrary DPCPU message.
+ */
+#define MC_CMD_DPCPU_RPC 0xae
+#undef MC_CMD_0xae_PRIVILEGE_CTG
+
+#define MC_CMD_0xae_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DPCPU_RPC_IN msgrequest */
+#define MC_CMD_DPCPU_RPC_IN_LEN 36
+#define MC_CMD_DPCPU_RPC_IN_CPU_OFST 0
+/* enum: RxDPCPU0 */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX0 0x0
+/* enum: TxDPCPU0 */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX0 0x1
+/* enum: TxDPCPU1 */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX1 0x2
+/* enum: RxDPCPU1 (Medford only) */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX1 0x3
+/* enum: RxDPCPU (will be for the calling function; for now, just an alias of
+ * DPCPU_RX0)
+ */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX 0x80
+/* enum: TxDPCPU (will be for the calling function; for now, just an alias of
+ * DPCPU_TX0)
+ */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX 0x81
+/* First 8 bits [39:32] of DATA are consumed by MC-DPCPU protocol and must be
+ * initialised to zero
+ */
+#define MC_CMD_DPCPU_RPC_IN_DATA_OFST 4
+#define MC_CMD_DPCPU_RPC_IN_DATA_LEN 32
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_LBN 8
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_WIDTH 8
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_READ 0x6 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_WRITE 0x7 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_SELF_TEST 0xc /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_CSR_ACCESS 0xe /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_READ 0x46 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_WRITE 0x47 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SELF_TEST 0x4a /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_CSR_ACCESS 0x4c /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SET_MC_REPLAY_CNTXT 0x4d /* enum */
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_COUNT_LBN 48
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_COUNT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_WIDTH 240
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_STOP_RETURN_RESULT 0x0 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_READ 0x1 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE 0x2 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE_READ 0x3 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_PIPELINED_READ 0x4 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_LBN 48
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_LBN 64
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_LBN 80
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_CUT_THROUGH 0x1 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD 0x2 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD_FIRST 0x3 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_LBN 64
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_WDATA_OFST 12
+#define MC_CMD_DPCPU_RPC_IN_WDATA_LEN 24
+/* Register data to write. Only valid in write/write-read. */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_DATA_OFST 16
+/* Register address. */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_ADDRESS_OFST 20
+
+/* MC_CMD_DPCPU_RPC_OUT msgresponse */
+#define MC_CMD_DPCPU_RPC_OUT_LEN 36
+#define MC_CMD_DPCPU_RPC_OUT_RC_OFST 0
+/* DATA */
+#define MC_CMD_DPCPU_RPC_OUT_DATA_OFST 4
+#define MC_CMD_DPCPU_RPC_OUT_DATA_LEN 32
+#define MC_CMD_DPCPU_RPC_OUT_HDR_CMD_RESP_ERRCODE_LBN 32
+#define MC_CMD_DPCPU_RPC_OUT_HDR_CMD_RESP_ERRCODE_WIDTH 16
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_COUNT_LBN 48
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_COUNT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_OUT_RDATA_OFST 12
+#define MC_CMD_DPCPU_RPC_OUT_RDATA_LEN 24
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_1_OFST 12
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_2_OFST 16
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_3_OFST 20
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_4_OFST 24
+
+
+/***********************************/
+/* MC_CMD_TRIGGER_INTERRUPT
+ * Trigger an interrupt by prodding the BIU.
+ */
+#define MC_CMD_TRIGGER_INTERRUPT 0xe3
+#undef MC_CMD_0xe3_PRIVILEGE_CTG
+
+#define MC_CMD_0xe3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_TRIGGER_INTERRUPT_IN msgrequest */
+#define MC_CMD_TRIGGER_INTERRUPT_IN_LEN 4
+/* Interrupt level relative to base for function. */
+#define MC_CMD_TRIGGER_INTERRUPT_IN_INTR_LEVEL_OFST 0
+
+/* MC_CMD_TRIGGER_INTERRUPT_OUT msgresponse */
+#define MC_CMD_TRIGGER_INTERRUPT_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SHMBOOT_OP
+ * Special operations to support (for now) shmboot.
+ */
+#define MC_CMD_SHMBOOT_OP 0xe6
+#undef MC_CMD_0xe6_PRIVILEGE_CTG
+
+#define MC_CMD_0xe6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SHMBOOT_OP_IN msgrequest */
+#define MC_CMD_SHMBOOT_OP_IN_LEN 4
+/* Identifies the operation to perform */
+#define MC_CMD_SHMBOOT_OP_IN_SHMBOOT_OP_OFST 0
+/* enum: Copy slave_data section to the slave core. (Greenport only) */
+#define MC_CMD_SHMBOOT_OP_IN_PUSH_SLAVE_DATA 0x0
+
+/* MC_CMD_SHMBOOT_OP_OUT msgresponse */
+#define MC_CMD_SHMBOOT_OP_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_CAP_BLK_READ
+ * Read multiple 64bit words from capture block memory
+ */
+#define MC_CMD_CAP_BLK_READ 0xe7
+#undef MC_CMD_0xe7_PRIVILEGE_CTG
+
+#define MC_CMD_0xe7_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_CAP_BLK_READ_IN msgrequest */
+#define MC_CMD_CAP_BLK_READ_IN_LEN 12
+#define MC_CMD_CAP_BLK_READ_IN_CAP_REG_OFST 0
+#define MC_CMD_CAP_BLK_READ_IN_ADDR_OFST 4
+#define MC_CMD_CAP_BLK_READ_IN_COUNT_OFST 8
+
+/* MC_CMD_CAP_BLK_READ_OUT msgresponse */
+#define MC_CMD_CAP_BLK_READ_OUT_LENMIN 8
+#define MC_CMD_CAP_BLK_READ_OUT_LENMAX 248
+#define MC_CMD_CAP_BLK_READ_OUT_LEN(num) (0+8*(num))
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_OFST 0
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_LEN 8
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_LO_OFST 0
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_HI_OFST 4
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MINNUM 1
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MAXNUM 31
+
+
+/***********************************/
+/* MC_CMD_DUMP_DO
+ * Take a dump of the DUT state
+ */
+#define MC_CMD_DUMP_DO 0xe8
+#undef MC_CMD_0xe8_PRIVILEGE_CTG
+
+#define MC_CMD_0xe8_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DUMP_DO_IN msgrequest */
+#define MC_CMD_DUMP_DO_IN_LEN 52
+#define MC_CMD_DUMP_DO_IN_PADDING_OFST 0
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_OFST 4
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM 0x0 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_DEFAULT 0x1 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_TYPE_OFST 8
+#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_NVRAM 0x1 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY 0x2 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY_MLI 0x3 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_UART 0x4 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 12
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_OFST 16
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 12
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 16
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 12
+#define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_PAGE_SIZE 0x1000 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 16
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20
+#define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_MAX_DEPTH 0x2 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12
+/* enum: The uart port this command was received over (if using a uart
+ * transport)
+ */
+#define MC_CMD_DUMP_DO_IN_UART_PORT_SRC 0xff
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_OFST 28
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM 0x0 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_NVRAM_DUMP_PARTITION 0x1 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_TYPE_OFST 32
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 36
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_NVRAM_OFFSET_OFST 40
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 36
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 40
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 36
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 40
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 44
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_UART_PORT_OFST 36
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_SIZE_OFST 48
+
+/* MC_CMD_DUMP_DO_OUT msgresponse */
+#define MC_CMD_DUMP_DO_OUT_LEN 4
+#define MC_CMD_DUMP_DO_OUT_DUMPFILE_SIZE_OFST 0
+
+
+/***********************************/
+/* MC_CMD_DUMP_CONFIGURE_UNSOLICITED
+ * Configure unsolicited dumps
+ */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED 0xe9
+#undef MC_CMD_0xe9_PRIVILEGE_CTG
+
+#define MC_CMD_0xe9_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN msgrequest */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_LEN 52
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_ENABLE_OFST 0
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_OFST 4
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_TYPE_OFST 8
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 12
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_OFST 16
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 12
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 16
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 12
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 16
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_OFST 28
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPFILE_DST */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_TYPE_OFST 32
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 36
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_NVRAM_OFFSET_OFST 40
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 36
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 40
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 36
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 40
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 44
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_UART_PORT_OFST 36
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_SIZE_OFST 48
+
+
+/***********************************/
+/* MC_CMD_SET_PSU
+ * Adjusts power supply parameters. This is a warranty-voiding operation.
+ * Returns: ENOENT if the parameter or rail specified does not exist, EINVAL if
+ * the parameter is out of range.
+ */
+#define MC_CMD_SET_PSU 0xea
+#undef MC_CMD_0xea_PRIVILEGE_CTG
+
+#define MC_CMD_0xea_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_PSU_IN msgrequest */
+#define MC_CMD_SET_PSU_IN_LEN 12
+#define MC_CMD_SET_PSU_IN_PARAM_OFST 0
+#define MC_CMD_SET_PSU_IN_PARAM_SUPPLY_VOLTAGE 0x0 /* enum */
+#define MC_CMD_SET_PSU_IN_RAIL_OFST 4
+#define MC_CMD_SET_PSU_IN_RAIL_0V9 0x0 /* enum */
+#define MC_CMD_SET_PSU_IN_RAIL_1V2 0x1 /* enum */
+/* desired value, eg voltage in mV */
+#define MC_CMD_SET_PSU_IN_VALUE_OFST 8
+
+/* MC_CMD_SET_PSU_OUT msgresponse */
+#define MC_CMD_SET_PSU_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_FUNCTION_INFO
+ * Get function information. PF and VF number.
+ */
+#define MC_CMD_GET_FUNCTION_INFO 0xec
+#undef MC_CMD_0xec_PRIVILEGE_CTG
+
+#define MC_CMD_0xec_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_FUNCTION_INFO_IN msgrequest */
+#define MC_CMD_GET_FUNCTION_INFO_IN_LEN 0
+
+/* MC_CMD_GET_FUNCTION_INFO_OUT msgresponse */
+#define MC_CMD_GET_FUNCTION_INFO_OUT_LEN 8
+#define MC_CMD_GET_FUNCTION_INFO_OUT_PF_OFST 0
+#define MC_CMD_GET_FUNCTION_INFO_OUT_VF_OFST 4
+
+
+/***********************************/
+/* MC_CMD_ENABLE_OFFLINE_BIST
+ * Enters offline BIST mode. All queues are torn down, chip enters quiescent
+ * mode, calling function gets exclusive MCDI ownership. The only way out is
+ * reboot.
+ */
+#define MC_CMD_ENABLE_OFFLINE_BIST 0xed
+#undef MC_CMD_0xed_PRIVILEGE_CTG
+
+#define MC_CMD_0xed_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_ENABLE_OFFLINE_BIST_IN msgrequest */
+#define MC_CMD_ENABLE_OFFLINE_BIST_IN_LEN 0
+
+/* MC_CMD_ENABLE_OFFLINE_BIST_OUT msgresponse */
+#define MC_CMD_ENABLE_OFFLINE_BIST_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_UART_SEND_DATA
+ * Send checksummed[sic] block of data over the uart. Response is a placeholder
+ * should we wish to make this reliable; currently requests are fire-and-
+ * forget.
+ */
+#define MC_CMD_UART_SEND_DATA 0xee
+#undef MC_CMD_0xee_PRIVILEGE_CTG
+
+#define MC_CMD_0xee_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_UART_SEND_DATA_OUT msgrequest */
+#define MC_CMD_UART_SEND_DATA_OUT_LENMIN 16
+#define MC_CMD_UART_SEND_DATA_OUT_LENMAX 252
+#define MC_CMD_UART_SEND_DATA_OUT_LEN(num) (16+1*(num))
+/* CRC32 over OFFSET, LENGTH, RESERVED, DATA */
+#define MC_CMD_UART_SEND_DATA_OUT_CHECKSUM_OFST 0
+/* Offset at which to write the data */
+#define MC_CMD_UART_SEND_DATA_OUT_OFFSET_OFST 4
+/* Length of data */
+#define MC_CMD_UART_SEND_DATA_OUT_LENGTH_OFST 8
+/* Reserved for future use */
+#define MC_CMD_UART_SEND_DATA_OUT_RESERVED_OFST 12
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_OFST 16
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_LEN 1
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_MINNUM 0
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_MAXNUM 236
+
+/* MC_CMD_UART_SEND_DATA_IN msgresponse */
+#define MC_CMD_UART_SEND_DATA_IN_LEN 0
+
+
+/***********************************/
+/* MC_CMD_UART_RECV_DATA
+ * Request checksummed[sic] block of data over the uart. Only a placeholder,
+ * subject to change and not currently implemented.
+ */
+#define MC_CMD_UART_RECV_DATA 0xef
+#undef MC_CMD_0xef_PRIVILEGE_CTG
+
+#define MC_CMD_0xef_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_UART_RECV_DATA_OUT msgrequest */
+#define MC_CMD_UART_RECV_DATA_OUT_LEN 16
+/* CRC32 over OFFSET, LENGTH, RESERVED */
+#define MC_CMD_UART_RECV_DATA_OUT_CHECKSUM_OFST 0
+/* Offset from which to read the data */
+#define MC_CMD_UART_RECV_DATA_OUT_OFFSET_OFST 4
+/* Length of data */
+#define MC_CMD_UART_RECV_DATA_OUT_LENGTH_OFST 8
+/* Reserved for future use */
+#define MC_CMD_UART_RECV_DATA_OUT_RESERVED_OFST 12
+
+/* MC_CMD_UART_RECV_DATA_IN msgresponse */
+#define MC_CMD_UART_RECV_DATA_IN_LENMIN 16
+#define MC_CMD_UART_RECV_DATA_IN_LENMAX 252
+#define MC_CMD_UART_RECV_DATA_IN_LEN(num) (16+1*(num))
+/* CRC32 over RESERVED1, RESERVED2, RESERVED3, DATA */
+#define MC_CMD_UART_RECV_DATA_IN_CHECKSUM_OFST 0
+/* Offset at which to write the data */
+#define MC_CMD_UART_RECV_DATA_IN_RESERVED1_OFST 4
+/* Length of data */
+#define MC_CMD_UART_RECV_DATA_IN_RESERVED2_OFST 8
+/* Reserved for future use */
+#define MC_CMD_UART_RECV_DATA_IN_RESERVED3_OFST 12
+#define MC_CMD_UART_RECV_DATA_IN_DATA_OFST 16
+#define MC_CMD_UART_RECV_DATA_IN_DATA_LEN 1
+#define MC_CMD_UART_RECV_DATA_IN_DATA_MINNUM 0
+#define MC_CMD_UART_RECV_DATA_IN_DATA_MAXNUM 236
+
+
+/***********************************/
+/* MC_CMD_READ_FUSES
+ * Read data programmed into the device One-Time-Programmable (OTP) Fuses
+ */
+#define MC_CMD_READ_FUSES 0xf0
+#undef MC_CMD_0xf0_PRIVILEGE_CTG
+
+#define MC_CMD_0xf0_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_READ_FUSES_IN msgrequest */
+#define MC_CMD_READ_FUSES_IN_LEN 8
+/* Offset in OTP to read */
+#define MC_CMD_READ_FUSES_IN_OFFSET_OFST 0
+/* Length of data to read in bytes */
+#define MC_CMD_READ_FUSES_IN_LENGTH_OFST 4
+
+/* MC_CMD_READ_FUSES_OUT msgresponse */
+#define MC_CMD_READ_FUSES_OUT_LENMIN 4
+#define MC_CMD_READ_FUSES_OUT_LENMAX 252
+#define MC_CMD_READ_FUSES_OUT_LEN(num) (4+1*(num))
+/* Length of returned OTP data in bytes */
+#define MC_CMD_READ_FUSES_OUT_LENGTH_OFST 0
+/* Returned data */
+#define MC_CMD_READ_FUSES_OUT_DATA_OFST 4
+#define MC_CMD_READ_FUSES_OUT_DATA_LEN 1
+#define MC_CMD_READ_FUSES_OUT_DATA_MINNUM 0
+#define MC_CMD_READ_FUSES_OUT_DATA_MAXNUM 248
+
+
+/***********************************/
+/* MC_CMD_KR_TUNE
+ * Get or set KR Serdes RXEQ and TX Driver settings
+ */
+#define MC_CMD_KR_TUNE 0xf1
+#undef MC_CMD_0xf1_PRIVILEGE_CTG
+
+#define MC_CMD_0xf1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_KR_TUNE_IN msgrequest */
+#define MC_CMD_KR_TUNE_IN_LENMIN 4
+#define MC_CMD_KR_TUNE_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_IN_LEN(num) (4+4*(num))
+/* Requested operation */
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_LEN 1
+/* enum: Get current RXEQ settings */
+#define MC_CMD_KR_TUNE_IN_RXEQ_GET 0x0
+/* enum: Override RXEQ settings */
+#define MC_CMD_KR_TUNE_IN_RXEQ_SET 0x1
+/* enum: Get current TX Driver settings */
+#define MC_CMD_KR_TUNE_IN_TXEQ_GET 0x2
+/* enum: Override TX Driver settings */
+#define MC_CMD_KR_TUNE_IN_TXEQ_SET 0x3
+/* enum: Force KR Serdes reset / recalibration */
+#define MC_CMD_KR_TUNE_IN_RECAL 0x4
+/* enum: Start KR Serdes Eye diagram plot on a given lane. Lane must have valid
+ * signal.
+ */
+#define MC_CMD_KR_TUNE_IN_START_EYE_PLOT 0x5
+/* enum: Poll KR Serdes Eye diagram plot. Returns one row of BER data. The
+ * caller should call this command repeatedly after starting eye plot, until no
+ * more data is returned.
+ */
+#define MC_CMD_KR_TUNE_IN_POLL_EYE_PLOT 0x6
+/* enum: Read Figure Of Merit (eye quality, higher is better). */
+#define MC_CMD_KR_TUNE_IN_READ_FOM 0x7
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_LEN 3
+/* Arguments specific to the operation */
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_OFST 4
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_LEN 4
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_MINNUM 0
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_MAXNUM 62
+
+/* MC_CMD_KR_TUNE_OUT msgresponse */
+#define MC_CMD_KR_TUNE_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_RXEQ_GET_IN msgrequest */
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_KR_TUNE_RSVD_LEN 3
+
+/* MC_CMD_KR_TUNE_RXEQ_GET_OUT msgresponse */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LENMIN 4
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LEN(num) (0+4*(num))
+/* RXEQ Parameter */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_OFST 0
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LEN 4
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_MINNUM 1
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8
+/* enum: Attenuation (0-15, TBD for Medford) */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_ATT 0x0
+/* enum: CTLE Boost (0-15, TBD for Medford) */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_BOOST 0x1
+/* enum: Edge DFE Tap1 (0 - max negative, 64 - zero, 127 - max positive, TBD
+ * for Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP1 0x2
+/* enum: Edge DFE Tap2 (0 - max negative, 32 - zero, 63 - max positive, TBD for
+ * Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP2 0x3
+/* enum: Edge DFE Tap3 (0 - max negative, 32 - zero, 63 - max positive, TBD for
+ * Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP3 0x4
+/* enum: Edge DFE Tap4 (0 - max negative, 32 - zero, 63 - max positive, TBD for
+ * Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP4 0x5
+/* enum: Edge DFE Tap5 (0 - max negative, 32 - zero, 63 - max positive, TBD for
+ * Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP5 0x6
+/* enum: Edge DFE DLEV (TBD for Medford) */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_DLEV 0x7
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 3
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_1 0x1 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_ALL 0x4 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_LBN 11
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_WIDTH 1
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_LBN 12
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_WIDTH 4
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_INITIAL_LBN 16
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_LBN 24
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
+
+/* MC_CMD_KR_TUNE_RXEQ_SET_IN msgrequest */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LENMIN 8
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LEN(num) (4+4*(num))
+/* Requested operation */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_RSVD_LEN 3
+/* RXEQ Parameter */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_OFST 4
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LEN 4
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_MINNUM 1
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_MAXNUM 62
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_ID_LBN 0
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_ID_WIDTH 8
+/* Enum values, see field(s): */
+/* MC_CMD_KR_TUNE_RXEQ_GET_OUT/PARAM_ID */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LANE_LBN 8
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LANE_WIDTH 3
+/* Enum values, see field(s): */
+/* MC_CMD_KR_TUNE_RXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_LBN 11
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_WIDTH 1
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED_LBN 12
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED_WIDTH 4
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_INITIAL_LBN 16
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED2_LBN 24
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED2_WIDTH 8
+
+/* MC_CMD_KR_TUNE_RXEQ_SET_OUT msgresponse */
+#define MC_CMD_KR_TUNE_RXEQ_SET_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_TXEQ_GET_IN msgrequest */
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_RSVD_LEN 3
+
+/* MC_CMD_KR_TUNE_TXEQ_GET_OUT msgresponse */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMIN 4
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LEN(num) (0+4*(num))
+/* TXEQ Parameter */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_OFST 0
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LEN 4
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MINNUM 1
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8
+/* enum: TX Amplitude */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV 0x0
+/* enum: De-Emphasis Tap1 Magnitude (0-7) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_MODE 0x1
+/* enum: De-Emphasis Tap1 Fine */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_DTLEV 0x2
+/* enum: De-Emphasis Tap2 Magnitude (0-6) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2 0x3
+/* enum: De-Emphasis Tap2 Fine */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2TLEV 0x4
+/* enum: Pre-Emphasis Magnitude */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_E 0x5
+/* enum: Pre-Emphasis Fine */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_ETLEV 0x6
+/* enum: TX Slew Rate Coarse control */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_PREDRV_DLY 0x7
+/* enum: TX Slew Rate Fine control */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_SR_SET 0x8
+/* enum: TX Termination Impedance control */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_RT_SET 0x9
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 3
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_0 0x0 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_1 0x1 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_2 0x2 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_3 0x3 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_ALL 0x4 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_LBN 11
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 5
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_LBN 16
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_LBN 24
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_WIDTH 8
+
+/* MC_CMD_KR_TUNE_TXEQ_SET_IN msgrequest */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMIN 8
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LEN(num) (4+4*(num))
+/* Requested operation */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_RSVD_LEN 3
+/* TXEQ Parameter */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_OFST 4
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LEN 4
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MINNUM 1
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MAXNUM 62
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_LBN 0
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_WIDTH 8
+/* Enum values, see field(s): */
+/* MC_CMD_KR_TUNE_TXEQ_GET_OUT/PARAM_ID */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_LBN 8
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_WIDTH 3
+/* Enum values, see field(s): */
+/* MC_CMD_KR_TUNE_TXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_LBN 11
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_WIDTH 5
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_LBN 16
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_LBN 24
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_WIDTH 8
+
+/* MC_CMD_KR_TUNE_TXEQ_SET_OUT msgresponse */
+#define MC_CMD_KR_TUNE_TXEQ_SET_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_RECAL_IN msgrequest */
+#define MC_CMD_KR_TUNE_RECAL_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_KR_TUNE_RECAL_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_RECAL_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_RECAL_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_RECAL_IN_KR_TUNE_RSVD_LEN 3
+
+/* MC_CMD_KR_TUNE_RECAL_OUT msgresponse */
+#define MC_CMD_KR_TUNE_RECAL_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_START_EYE_PLOT_IN msgrequest */
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_LEN 8
+/* Requested operation */
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_RSVD_LEN 3
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_LANE_OFST 4
+
+/* MC_CMD_KR_TUNE_START_EYE_PLOT_OUT msgresponse */
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN msgrequest */
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_RSVD_LEN 3
+
+/* MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT msgresponse */
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMIN 0
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LEN(num) (0+2*(num))
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_OFST 0
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_LEN 2
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MINNUM 0
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM 126
+
+/* MC_CMD_KR_TUNE_READ_FOM_IN msgrequest */
+#define MC_CMD_KR_TUNE_READ_FOM_IN_LEN 8
+/* Requested operation */
+#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_LEN 3
+#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_OFST 4
+
+/* MC_CMD_KR_TUNE_READ_FOM_OUT msgresponse */
+#define MC_CMD_KR_TUNE_READ_FOM_OUT_LEN 4
+#define MC_CMD_KR_TUNE_READ_FOM_OUT_FOM_OFST 0
+
+
+/***********************************/
+/* MC_CMD_PCIE_TUNE
+ * Get or set PCIE Serdes RXEQ and TX Driver settings
+ */
+#define MC_CMD_PCIE_TUNE 0xf2
+#undef MC_CMD_0xf2_PRIVILEGE_CTG
+
+#define MC_CMD_0xf2_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_PCIE_TUNE_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_IN_LENMIN 4
+#define MC_CMD_PCIE_TUNE_IN_LENMAX 252
+#define MC_CMD_PCIE_TUNE_IN_LEN(num) (4+4*(num))
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_LEN 1
+/* enum: Get current RXEQ settings */
+#define MC_CMD_PCIE_TUNE_IN_RXEQ_GET 0x0
+/* enum: Override RXEQ settings */
+#define MC_CMD_PCIE_TUNE_IN_RXEQ_SET 0x1
+/* enum: Get current TX Driver settings */
+#define MC_CMD_PCIE_TUNE_IN_TXEQ_GET 0x2
+/* enum: Override TX Driver settings */
+#define MC_CMD_PCIE_TUNE_IN_TXEQ_SET 0x3
+/* enum: Start PCIe Serdes Eye diagram plot on a given lane. */
+#define MC_CMD_PCIE_TUNE_IN_START_EYE_PLOT 0x5
+/* enum: Poll PCIe Serdes Eye diagram plot. Returns one row of BER data. The
+ * caller should call this command repeatedly after starting eye plot, until no
+ * more data is returned.
+ */
+#define MC_CMD_PCIE_TUNE_IN_POLL_EYE_PLOT 0x6
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_LEN 3
+/* Arguments specific to the operation */
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_OFST 4
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_LEN 4
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_MINNUM 0
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_MAXNUM 62
+
+/* MC_CMD_PCIE_TUNE_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_OUT_LEN 0
+
+/* MC_CMD_PCIE_TUNE_RXEQ_GET_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_PCIE_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_PCIE_TUNE_RSVD_LEN 3
+
+/* MC_CMD_PCIE_TUNE_RXEQ_GET_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LENMIN 4
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LEN(num) (0+4*(num))
+/* RXEQ Parameter */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_OFST 0
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LEN 4
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_MINNUM 1
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8
+/* enum: Attenuation (0-15) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_ATT 0x0
+/* enum: CTLE Boost (0-15) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_BOOST 0x1
+/* enum: DFE Tap1 (0 - max negative, 64 - zero, 127 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP1 0x2
+/* enum: DFE Tap2 (0 - max negative, 32 - zero, 63 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP2 0x3
+/* enum: DFE Tap3 (0 - max negative, 32 - zero, 63 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP3 0x4
+/* enum: DFE Tap4 (0 - max negative, 32 - zero, 63 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP4 0x5
+/* enum: DFE Tap5 (0 - max negative, 32 - zero, 63 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP5 0x6
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 4
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_1 0x1 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_4 0x4 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_5 0x5 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_6 0x6 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_7 0x7 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_ALL 0x8 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_LBN 12
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_WIDTH 12
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_LBN 24
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
+
+/* MC_CMD_PCIE_TUNE_TXEQ_GET_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_PCIE_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_PCIE_TUNE_RSVD_LEN 3
+
+/* MC_CMD_PCIE_TUNE_TXEQ_GET_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LENMIN 4
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LEN(num) (0+4*(num))
+/* RXEQ Parameter */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_OFST 0
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LEN 4
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_MINNUM 1
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8
+/* enum: TxMargin (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_TXMARGIN 0x0
+/* enum: TxSwing (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_TXSWING 0x1
+/* enum: De-emphasis coefficient C(-1) (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CM1 0x2
+/* enum: De-emphasis coefficient C(0) (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_C0 0x3
+/* enum: De-emphasis coefficient C(+1) (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CP1 0x4
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 4
+/* Enum values, see field(s): */
+/* MC_CMD_PCIE_TUNE_RXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_RESERVED_LBN 12
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 12
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_LBN 24
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
+
+/* MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_LEN 8
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_RSVD_LEN 3
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_LANE_OFST 4
+
+/* MC_CMD_PCIE_TUNE_START_EYE_PLOT_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_OUT_LEN 0
+
+/* MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_RSVD_LEN 3
+
+/* MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMIN 0
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LEN(num) (0+2*(num))
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_OFST 0
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_LEN 2
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MINNUM 0
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM 126
+
+
+/***********************************/
+/* MC_CMD_LICENSING
+ * Operations on the NVRAM_PARTITION_TYPE_LICENSE application license partition
+ */
+#define MC_CMD_LICENSING 0xf3
+#undef MC_CMD_0xf3_PRIVILEGE_CTG
+
+#define MC_CMD_0xf3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_LICENSING_IN msgrequest */
+#define MC_CMD_LICENSING_IN_LEN 4
+/* identifies the type of operation requested */
+#define MC_CMD_LICENSING_IN_OP_OFST 0
+/* enum: re-read and apply licenses after a license key partition update; note
+ * that this operation returns a zero-length response
+ */
+#define MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE 0x0
+/* enum: report counts of installed licenses */
+#define MC_CMD_LICENSING_IN_OP_GET_KEY_STATS 0x1
+
+/* MC_CMD_LICENSING_OUT msgresponse */
+#define MC_CMD_LICENSING_OUT_LEN 28
+/* count of application keys which are valid */
+#define MC_CMD_LICENSING_OUT_VALID_APP_KEYS_OFST 0
+/* sum of UNVERIFIABLE_APP_KEYS + WRONG_NODE_APP_KEYS (for compatibility with
+ * MC_CMD_FC_OP_LICENSE)
+ */
+#define MC_CMD_LICENSING_OUT_INVALID_APP_KEYS_OFST 4
+/* count of application keys which are invalid due to being blacklisted */
+#define MC_CMD_LICENSING_OUT_BLACKLISTED_APP_KEYS_OFST 8
+/* count of application keys which are invalid due to being unverifiable */
+#define MC_CMD_LICENSING_OUT_UNVERIFIABLE_APP_KEYS_OFST 12
+/* count of application keys which are invalid due to being for the wrong node
+ */
+#define MC_CMD_LICENSING_OUT_WRONG_NODE_APP_KEYS_OFST 16
+/* licensing state (for diagnostics; the exact meaning of the bits in this
+ * field are private to the firmware)
+ */
+#define MC_CMD_LICENSING_OUT_LICENSING_STATE_OFST 20
+/* licensing subsystem self-test report (for manftest) */
+#define MC_CMD_LICENSING_OUT_LICENSING_SELF_TEST_OFST 24
+/* enum: licensing subsystem self-test failed */
+#define MC_CMD_LICENSING_OUT_SELF_TEST_FAIL 0x0
+/* enum: licensing subsystem self-test passed */
+#define MC_CMD_LICENSING_OUT_SELF_TEST_PASS 0x1
+
+
+/***********************************/
+/* MC_CMD_MC2MC_PROXY
+ * Execute an arbitrary MCDI command on the slave MC of a dual-core device.
+ * This will fail on a single-core system.
+ */
+#define MC_CMD_MC2MC_PROXY 0xf4
+#undef MC_CMD_0xf4_PRIVILEGE_CTG
+
+#define MC_CMD_0xf4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_MC2MC_PROXY_IN msgrequest */
+#define MC_CMD_MC2MC_PROXY_IN_LEN 0
+
+/* MC_CMD_MC2MC_PROXY_OUT msgresponse */
+#define MC_CMD_MC2MC_PROXY_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_LICENSED_APP_STATE
+ * Query the state of an individual licensed application. (Note that the actual
+ * state may be invalidated by the MC_CMD_LICENSING OP_UPDATE_LICENSE operation
+ * or a reboot of the MC.)
+ */
+#define MC_CMD_GET_LICENSED_APP_STATE 0xf5
+#undef MC_CMD_0xf5_PRIVILEGE_CTG
+
+#define MC_CMD_0xf5_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_LICENSED_APP_STATE_IN msgrequest */
+#define MC_CMD_GET_LICENSED_APP_STATE_IN_LEN 4
+/* application ID to query (LICENSED_APP_ID_xxx) */
+#define MC_CMD_GET_LICENSED_APP_STATE_IN_APP_ID_OFST 0
+
+/* MC_CMD_GET_LICENSED_APP_STATE_OUT msgresponse */
+#define MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN 4
+/* state of this application */
+#define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_OFST 0
+/* enum: no (or invalid) license is present for the application */
+#define MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED 0x0
+/* enum: a valid license is present for the application */
+#define MC_CMD_GET_LICENSED_APP_STATE_OUT_LICENSED 0x1
+
+
+/***********************************/
+/* MC_CMD_LICENSED_APP_OP
+ * Perform an action for an individual licensed application.
+ */
+#define MC_CMD_LICENSED_APP_OP 0xf6
+#undef MC_CMD_0xf6_PRIVILEGE_CTG
+
+#define MC_CMD_0xf6_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_LICENSED_APP_OP_IN msgrequest */
+#define MC_CMD_LICENSED_APP_OP_IN_LENMIN 8
+#define MC_CMD_LICENSED_APP_OP_IN_LENMAX 252
+#define MC_CMD_LICENSED_APP_OP_IN_LEN(num) (8+4*(num))
+/* application ID */
+#define MC_CMD_LICENSED_APP_OP_IN_APP_ID_OFST 0
+/* the type of operation requested */
+#define MC_CMD_LICENSED_APP_OP_IN_OP_OFST 4
+/* enum: validate application */
+#define MC_CMD_LICENSED_APP_OP_IN_OP_VALIDATE 0x0
+/* enum: mask application */
+#define MC_CMD_LICENSED_APP_OP_IN_OP_MASK 0x1
+/* arguments specific to this particular operation */
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_OFST 8
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_LEN 4
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_MINNUM 0
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_MAXNUM 61
+
+/* MC_CMD_LICENSED_APP_OP_OUT msgresponse */
+#define MC_CMD_LICENSED_APP_OP_OUT_LENMIN 0
+#define MC_CMD_LICENSED_APP_OP_OUT_LENMAX 252
+#define MC_CMD_LICENSED_APP_OP_OUT_LEN(num) (0+4*(num))
+/* result specific to this particular operation */
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_OFST 0
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_LEN 4
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MINNUM 0
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MAXNUM 63
+
+/* MC_CMD_LICENSED_APP_OP_VALIDATE_IN msgrequest */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_LEN 72
+/* application ID */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_APP_ID_OFST 0
+/* the type of operation requested */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_OP_OFST 4
+/* validation challenge */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_CHALLENGE_OFST 8
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_CHALLENGE_LEN 64
+
+/* MC_CMD_LICENSED_APP_OP_VALIDATE_OUT msgresponse */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_LEN 68
+/* feature expiry (time_t) */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_EXPIRY_OFST 0
+/* validation response */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_RESPONSE_OFST 4
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_RESPONSE_LEN 64
+
+/* MC_CMD_LICENSED_APP_OP_MASK_IN msgrequest */
+#define MC_CMD_LICENSED_APP_OP_MASK_IN_LEN 12
+/* application ID */
+#define MC_CMD_LICENSED_APP_OP_MASK_IN_APP_ID_OFST 0
+/* the type of operation requested */
+#define MC_CMD_LICENSED_APP_OP_MASK_IN_OP_OFST 4
+/* flag */
+#define MC_CMD_LICENSED_APP_OP_MASK_IN_FLAG_OFST 8
+
+/* MC_CMD_LICENSED_APP_OP_MASK_OUT msgresponse */
+#define MC_CMD_LICENSED_APP_OP_MASK_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SET_PORT_SNIFF_CONFIG
+ * Configure RX port sniffing for the physical port associated with the calling
+ * function. Only a privileged function may change the port sniffing
+ * configuration. A copy of all traffic delivered to the host (non-promiscuous
+ * mode) or all traffic arriving at the port (promiscuous mode) may be
+ * delivered to a specific queue, or a set of queues with RSS.
+ */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG 0xf7
+#undef MC_CMD_0xf7_PRIVILEGE_CTG
+
+#define MC_CMD_0xf7_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_PORT_SNIFF_CONFIG_IN msgrequest */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_LEN 16
+/* configuration flags */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_LBN 1
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_WIDTH 1
+/* receive queue handle (for RSS mode, this is the base queue) */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_QUEUE_OFST 4
+/* receive mode */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8
+/* enum: receive to just the specified queue */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0
+/* enum: receive to multiple queues using RSS context */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1
+/* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note
+ * that these handles should be considered opaque to the host, although a value
+ * of 0xFFFFFFFF is guaranteed never to be a valid handle.
+ */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_OFST 12
+
+/* MC_CMD_SET_PORT_SNIFF_CONFIG_OUT msgresponse */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_PORT_SNIFF_CONFIG
+ * Obtain the current RX port sniffing configuration for the physical port
+ * associated with the calling function. Only a privileged function may read
+ * the configuration.
+ */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG 0xf8
+#undef MC_CMD_0xf8_PRIVILEGE_CTG
+
+#define MC_CMD_0xf8_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_PORT_SNIFF_CONFIG_IN msgrequest */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_IN_LEN 0
+
+/* MC_CMD_GET_PORT_SNIFF_CONFIG_OUT msgresponse */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_LEN 16
+/* configuration flags */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_LBN 1
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_WIDTH 1
+/* receiving queue handle (for RSS mode, this is the base queue) */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_OFST 4
+/* receive mode */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8
+/* enum: receiving to just the specified queue */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0
+/* enum: receiving to multiple queues using RSS context */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1
+/* RSS context (for RX_MODE_RSS) */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12
+
+
+/***********************************/
+/* MC_CMD_SET_PARSER_DISP_CONFIG
+ * Change configuration related to the parser-dispatcher subsystem.
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG 0xf9
+#undef MC_CMD_0xf9_PRIVILEGE_CTG
+
+#define MC_CMD_0xf9_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_SET_PARSER_DISP_CONFIG_IN msgrequest */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LENMIN 12
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LENMAX 252
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LEN(num) (8+4*(num))
+/* the type of configuration setting to change */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TYPE_OFST 0
+/* enum: Per-TXQ enable for multicast UDP destination lookup for possible
+ * internal loopback. (ENTITY is a queue handle, VALUE is a single boolean.)
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TXQ_MCAST_UDP_DST_LOOKUP_EN 0x0
+/* enum: Per-v-adaptor enable for suppression of self-transmissions on the
+ * internal loopback path. (ENTITY is an EVB_PORT_ID, VALUE is a single
+ * boolean.)
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VADAPTOR_SUPPRESS_SELF_TX 0x1
+/* handle for the entity to update: queue handle, EVB port ID, etc. depending
+ * on the type of configuration setting being changed
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_ENTITY_OFST 4
+/* new value: the details depend on the type of configuration setting being
+ * changed
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_OFST 8
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_LEN 4
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_MINNUM 1
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_MAXNUM 61
+
+/* MC_CMD_SET_PARSER_DISP_CONFIG_OUT msgresponse */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_PARSER_DISP_CONFIG
+ * Read configuration related to the parser-dispatcher subsystem.
+ */
+#define MC_CMD_GET_PARSER_DISP_CONFIG 0xfa
+#undef MC_CMD_0xfa_PRIVILEGE_CTG
+
+#define MC_CMD_0xfa_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_PARSER_DISP_CONFIG_IN msgrequest */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_IN_LEN 8
+/* the type of configuration setting to read */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_IN_TYPE_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_SET_PARSER_DISP_CONFIG/MC_CMD_SET_PARSER_DISP_CONFIG_IN/TYPE */
+/* handle for the entity to query: queue handle, EVB port ID, etc. depending on
+ * the type of configuration setting being read
+ */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_IN_ENTITY_OFST 4
+
+/* MC_CMD_GET_PARSER_DISP_CONFIG_OUT msgresponse */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LENMIN 4
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LENMAX 252
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LEN(num) (0+4*(num))
+/* current value: the details depend on the type of configuration setting being
+ * read
+ */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_OFST 0
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_LEN 4
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_MINNUM 1
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_MAXNUM 63
+
+
+/***********************************/
+/* MC_CMD_SET_TX_PORT_SNIFF_CONFIG
+ * Configure TX port sniffing for the physical port associated with the calling
+ * function. Only a privileged function may change the port sniffing
+ * configuration. A copy of all traffic transmitted through the port may be
+ * delivered to a specific queue, or a set of queues with RSS. Note that these
+ * packets are delivered with transmit timestamps in the packet prefix, not
+ * receive timestamps, so it is likely that the queue(s) will need to be
+ * dedicated as TX sniff receivers.
+ */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG 0xfb
+#undef MC_CMD_0xfb_PRIVILEGE_CTG
+
+#define MC_CMD_0xfb_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN msgrequest */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_LEN 16
+/* configuration flags */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1
+/* receive queue handle (for RSS mode, this is the base queue) */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_QUEUE_OFST 4
+/* receive mode */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8
+/* enum: receive to just the specified queue */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0
+/* enum: receive to multiple queues using RSS context */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1
+/* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note
+ * that these handles should be considered opaque to the host, although a value
+ * of 0xFFFFFFFF is guaranteed never to be a valid handle.
+ */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_OFST 12
+
+/* MC_CMD_SET_TX_PORT_SNIFF_CONFIG_OUT msgresponse */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_TX_PORT_SNIFF_CONFIG
+ * Obtain the current TX port sniffing configuration for the physical port
+ * associated with the calling function. Only a privileged function may read
+ * the configuration.
+ */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG 0xfc
+#undef MC_CMD_0xfc_PRIVILEGE_CTG
+
+#define MC_CMD_0xfc_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_TX_PORT_SNIFF_CONFIG_IN msgrequest */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_IN_LEN 0
+
+/* MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT msgresponse */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_LEN 16
+/* configuration flags */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1
+/* receiving queue handle (for RSS mode, this is the base queue) */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_OFST 4
+/* receive mode */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8
+/* enum: receiving to just the specified queue */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0
+/* enum: receiving to multiple queues using RSS context */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1
+/* RSS context (for RX_MODE_RSS) */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12
+
+
+/***********************************/
+/* MC_CMD_RMON_STATS_RX_ERRORS
+ * Per queue rx error stats.
+ */
+#define MC_CMD_RMON_STATS_RX_ERRORS 0xfe
+#undef MC_CMD_0xfe_PRIVILEGE_CTG
+
+#define MC_CMD_0xfe_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RMON_STATS_RX_ERRORS_IN msgrequest */
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_LEN 8
+/* The rx queue to get stats for. */
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RX_QUEUE_OFST 0
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_FLAGS_OFST 4
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_LBN 0
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_WIDTH 1
+
+/* MC_CMD_RMON_STATS_RX_ERRORS_OUT msgresponse */
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_LEN 16
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_CRC_ERRORS_OFST 0
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_TRUNC_ERRORS_OFST 4
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_RX_NO_DESC_DROPS_OFST 8
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_RX_ABORT_OFST 12
+
+
+/***********************************/
+/* MC_CMD_GET_PCIE_RESOURCE_INFO
+ * Find out about available PCIE resources
+ */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO 0xfd
+
+/* MC_CMD_GET_PCIE_RESOURCE_INFO_IN msgrequest */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_IN_LEN 0
+
+/* MC_CMD_GET_PCIE_RESOURCE_INFO_OUT msgresponse */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_LEN 28
+/* The maximum number of PFs the device can expose */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_PFS_OFST 0
+/* The maximum number of VFs the device can expose in total */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VFS_OFST 4
+/* The maximum number of MSI-X vectors the device can provide in total */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VECTORS_OFST 8
+/* the number of MSI-X vectors the device will allocate by default to each PF
+ */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_DEFAULT_PF_VECTORS_OFST 12
+/* the number of MSI-X vectors the device will allocate by default to each VF
+ */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_DEFAULT_VF_VECTORS_OFST 16
+/* the maximum number of MSI-X vectors the device can allocate to any one PF */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_PF_VECTORS_OFST 20
+/* the maximum number of MSI-X vectors the device can allocate to any one VF */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VF_VECTORS_OFST 24
+
+
+/***********************************/
+/* MC_CMD_GET_PORT_MODES
+ * Find out about available port modes
+ */
+#define MC_CMD_GET_PORT_MODES 0xff
+#undef MC_CMD_0xff_PRIVILEGE_CTG
+
+#define MC_CMD_0xff_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_PORT_MODES_IN msgrequest */
+#define MC_CMD_GET_PORT_MODES_IN_LEN 0
+
+/* MC_CMD_GET_PORT_MODES_OUT msgresponse */
+#define MC_CMD_GET_PORT_MODES_OUT_LEN 12
+/* Bitmask of port modes available on the board (indexed by TLV_PORT_MODE_*) */
+#define MC_CMD_GET_PORT_MODES_OUT_MODES_OFST 0
+/* Default (canonical) board mode */
+#define MC_CMD_GET_PORT_MODES_OUT_DEFAULT_MODE_OFST 4
+/* Current board mode */
+#define MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST 8
+
+
+/***********************************/
+/* MC_CMD_READ_ATB
+ * Sample voltages on the ATB
+ */
+#define MC_CMD_READ_ATB 0x100
+#undef MC_CMD_0x100_PRIVILEGE_CTG
+
+#define MC_CMD_0x100_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_READ_ATB_IN msgrequest */
+#define MC_CMD_READ_ATB_IN_LEN 16
+#define MC_CMD_READ_ATB_IN_SIGNAL_BUS_OFST 0
+#define MC_CMD_READ_ATB_IN_BUS_CCOM 0x0 /* enum */
+#define MC_CMD_READ_ATB_IN_BUS_CKR 0x1 /* enum */
+#define MC_CMD_READ_ATB_IN_BUS_CPCIE 0x8 /* enum */
+#define MC_CMD_READ_ATB_IN_SIGNAL_EN_BITNO_OFST 4
+#define MC_CMD_READ_ATB_IN_SIGNAL_SEL_OFST 8
+#define MC_CMD_READ_ATB_IN_SETTLING_TIME_US_OFST 12
+
+/* MC_CMD_READ_ATB_OUT msgresponse */
+#define MC_CMD_READ_ATB_OUT_LEN 4
+#define MC_CMD_READ_ATB_OUT_SAMPLE_MV_OFST 0
+
+
+/***********************************/
+/* MC_CMD_GET_WORKAROUNDS
+ * Read the list of all implemented and all currently enabled workarounds. The
+ * enums here must correspond with those in MC_CMD_WORKAROUND.
+ */
+#define MC_CMD_GET_WORKAROUNDS 0x59
+#undef MC_CMD_0x59_PRIVILEGE_CTG
+
+#define MC_CMD_0x59_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_WORKAROUNDS_OUT msgresponse */
+#define MC_CMD_GET_WORKAROUNDS_OUT_LEN 8
+/* Each workaround is represented by a single bit according to the enums below.
+ */
+#define MC_CMD_GET_WORKAROUNDS_OUT_IMPLEMENTED_OFST 0
+#define MC_CMD_GET_WORKAROUNDS_OUT_ENABLED_OFST 4
+/* enum: Bug 17230 work around. */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG17230 0x2
+/* enum: Bug 35388 work around (unsafe EVQ writes). */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG35388 0x4
+/* enum: Bug35017 workaround (A64 tables must be identity map) */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG35017 0x8
+/* enum: Bug 41750 present (MC_CMD_TRIGGER_INTERRUPT won't work) */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG41750 0x10
+/* enum: Bug 42008 present (Interrupts can overtake associated events). Caution
+ * - before adding code that queries this workaround, remember that there's
+ * released Monza firmware that doesn't understand MC_CMD_WORKAROUND_BUG42008,
+ * and will hence (incorrectly) report that the bug doesn't exist.
+ */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG42008 0x20
+/* enum: Bug 26807 features present in firmware (multicast filter chaining) */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG26807 0x40
+
+
+/***********************************/
+/* MC_CMD_PRIVILEGE_MASK
+ * Read/set privileges of an arbitrary PCIe function
+ */
+#define MC_CMD_PRIVILEGE_MASK 0x5a
+#undef MC_CMD_0x5a_PRIVILEGE_CTG
+
+#define MC_CMD_0x5a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_PRIVILEGE_MASK_IN msgrequest */
+#define MC_CMD_PRIVILEGE_MASK_IN_LEN 8
+/* The target function to have its mask read or set e.g. PF 0 = 0xFFFF0000, VF
+ * 1,3 = 0x00030001
+ */
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_OFST 0
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_LBN 0
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_LBN 16
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_WIDTH 16
+#define MC_CMD_PRIVILEGE_MASK_IN_VF_NULL 0xffff /* enum */
+/* New privilege mask to be set. The mask will only be changed if the MSB is
+ * set to 1.
+ */
+#define MC_CMD_PRIVILEGE_MASK_IN_NEW_MASK_OFST 4
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN 0x1 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK 0x2 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD 0x4 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP 0x8 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS 0x10 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING 0x20 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST 0x40 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST 0x80 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST 0x100 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST 0x200 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS 0x400 /* enum */
+/* enum: Set this bit to indicate that a new privilege mask is to be set,
+ * otherwise the command will only read the existing mask.
+ */
+#define MC_CMD_PRIVILEGE_MASK_IN_DO_CHANGE 0x80000000
+
+/* MC_CMD_PRIVILEGE_MASK_OUT msgresponse */
+#define MC_CMD_PRIVILEGE_MASK_OUT_LEN 4
+/* For an admin function, always all the privileges are reported. */
+#define MC_CMD_PRIVILEGE_MASK_OUT_OLD_MASK_OFST 0
+
+
+/***********************************/
+/* MC_CMD_LINK_STATE_MODE
+ * Read/set link state mode of a VF
+ */
+#define MC_CMD_LINK_STATE_MODE 0x5c
+#undef MC_CMD_0x5c_PRIVILEGE_CTG
+
+#define MC_CMD_0x5c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_LINK_STATE_MODE_IN msgrequest */
+#define MC_CMD_LINK_STATE_MODE_IN_LEN 8
+/* The target function to have its link state mode read or set, must be a VF
+ * e.g. VF 1,3 = 0x00030001
+ */
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_OFST 0
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_LBN 0
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_LBN 16
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_WIDTH 16
+/* New link state mode to be set */
+#define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_OFST 4
+#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO 0x0 /* enum */
+#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP 0x1 /* enum */
+#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN 0x2 /* enum */
+/* enum: Use this value to just read the existing setting without modifying it.
+ */
+#define MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE 0xffffffff
+
+/* MC_CMD_LINK_STATE_MODE_OUT msgresponse */
+#define MC_CMD_LINK_STATE_MODE_OUT_LEN 4
+#define MC_CMD_LINK_STATE_MODE_OUT_OLD_MODE_OFST 0
+
+
+/***********************************/
+/* MC_CMD_GET_SNAPSHOT_LENGTH
+ * Obtain the curent range of allowable values for the SNAPSHOT_LENGTH
+ * parameter to MC_CMD_INIT_RXQ.
+ */
+#define MC_CMD_GET_SNAPSHOT_LENGTH 0x101
+#undef MC_CMD_0x101_PRIVILEGE_CTG
+
+#define MC_CMD_0x101_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_SNAPSHOT_LENGTH_IN msgrequest */
+#define MC_CMD_GET_SNAPSHOT_LENGTH_IN_LEN 0
+
+/* MC_CMD_GET_SNAPSHOT_LENGTH_OUT msgresponse */
+#define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_LEN 8
+/* Minimum acceptable snapshot length. */
+#define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_RX_SNAPLEN_MIN_OFST 0
+/* Maximum acceptable snapshot length. */
+#define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_RX_SNAPLEN_MAX_OFST 4
+
+
+/***********************************/
+/* MC_CMD_FUSE_DIAGS
+ * Additional fuse diagnostics
+ */
+#define MC_CMD_FUSE_DIAGS 0x102
+#undef MC_CMD_0x102_PRIVILEGE_CTG
+
+#define MC_CMD_0x102_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_FUSE_DIAGS_IN msgrequest */
+#define MC_CMD_FUSE_DIAGS_IN_LEN 0
+
+/* MC_CMD_FUSE_DIAGS_OUT msgresponse */
+#define MC_CMD_FUSE_DIAGS_OUT_LEN 48
+/* Total number of mismatched bits between pairs in area 0 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA0_MISMATCH_BITS_OFST 0
+/* Total number of unexpectedly clear (set in B but not A) bits in area 0 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA0_PAIR_A_BAD_BITS_OFST 4
+/* Total number of unexpectedly clear (set in A but not B) bits in area 0 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA0_PAIR_B_BAD_BITS_OFST 8
+/* Checksum of data after logical OR of pairs in area 0 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA0_CHECKSUM_OFST 12
+/* Total number of mismatched bits between pairs in area 1 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA1_MISMATCH_BITS_OFST 16
+/* Total number of unexpectedly clear (set in B but not A) bits in area 1 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA1_PAIR_A_BAD_BITS_OFST 20
+/* Total number of unexpectedly clear (set in A but not B) bits in area 1 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA1_PAIR_B_BAD_BITS_OFST 24
+/* Checksum of data after logical OR of pairs in area 1 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA1_CHECKSUM_OFST 28
+/* Total number of mismatched bits between pairs in area 2 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA2_MISMATCH_BITS_OFST 32
+/* Total number of unexpectedly clear (set in B but not A) bits in area 2 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA2_PAIR_A_BAD_BITS_OFST 36
+/* Total number of unexpectedly clear (set in A but not B) bits in area 2 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA2_PAIR_B_BAD_BITS_OFST 40
+/* Checksum of data after logical OR of pairs in area 2 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA2_CHECKSUM_OFST 44
+
+
+/***********************************/
+/* MC_CMD_PRIVILEGE_MODIFY
+ * Modify the privileges of a set of PCIe functions. Note that this operation
+ * only effects non-admin functions unless the admin privilege itself is
+ * included in one of the masks provided.
+ */
+#define MC_CMD_PRIVILEGE_MODIFY 0x60
+#undef MC_CMD_0x60_PRIVILEGE_CTG
+
+#define MC_CMD_0x60_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_PRIVILEGE_MODIFY_IN msgrequest */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_LEN 16
+/* The groups of functions to have their privilege masks modified. */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FN_GROUP_OFST 0
+#define MC_CMD_PRIVILEGE_MODIFY_IN_NONE 0x0 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_ALL 0x1 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_PFS_ONLY 0x2 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_VFS_ONLY 0x3 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_VFS_OF_PF 0x4 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_ONE 0x5 /* enum */
+/* For VFS_OF_PF specify the PF, for ONE specify the target function */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_OFST 4
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_LBN 0
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_VF_LBN 16
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_VF_WIDTH 16
+/* Privileges to be added to the target functions. For privilege definitions
+ * refer to the command MC_CMD_PRIVILEGE_MASK
+ */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_ADD_MASK_OFST 8
+/* Privileges to be removed from the target functions. For privilege
+ * definitions refer to the command MC_CMD_PRIVILEGE_MASK
+ */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_REMOVE_MASK_OFST 12
+
+/* MC_CMD_PRIVILEGE_MODIFY_OUT msgresponse */
+#define MC_CMD_PRIVILEGE_MODIFY_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_READ_BYTES
+ * Read XPM memory
+ */
+#define MC_CMD_XPM_READ_BYTES 0x103
+#undef MC_CMD_0x103_PRIVILEGE_CTG
+
+#define MC_CMD_0x103_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_READ_BYTES_IN msgrequest */
+#define MC_CMD_XPM_READ_BYTES_IN_LEN 8
+/* Start address (byte) */
+#define MC_CMD_XPM_READ_BYTES_IN_ADDR_OFST 0
+/* Count (bytes) */
+#define MC_CMD_XPM_READ_BYTES_IN_COUNT_OFST 4
+
+/* MC_CMD_XPM_READ_BYTES_OUT msgresponse */
+#define MC_CMD_XPM_READ_BYTES_OUT_LENMIN 0
+#define MC_CMD_XPM_READ_BYTES_OUT_LENMAX 252
+#define MC_CMD_XPM_READ_BYTES_OUT_LEN(num) (0+1*(num))
+/* Data */
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_OFST 0
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_LEN 1
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_MINNUM 0
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_MAXNUM 252
+
+
+/***********************************/
+/* MC_CMD_XPM_WRITE_BYTES
+ * Write XPM memory
+ */
+#define MC_CMD_XPM_WRITE_BYTES 0x104
+#undef MC_CMD_0x104_PRIVILEGE_CTG
+
+#define MC_CMD_0x104_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_WRITE_BYTES_IN msgrequest */
+#define MC_CMD_XPM_WRITE_BYTES_IN_LENMIN 8
+#define MC_CMD_XPM_WRITE_BYTES_IN_LENMAX 252
+#define MC_CMD_XPM_WRITE_BYTES_IN_LEN(num) (8+1*(num))
+/* Start address (byte) */
+#define MC_CMD_XPM_WRITE_BYTES_IN_ADDR_OFST 0
+/* Count (bytes) */
+#define MC_CMD_XPM_WRITE_BYTES_IN_COUNT_OFST 4
+/* Data */
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_OFST 8
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_LEN 1
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_MINNUM 0
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_MAXNUM 244
+
+/* MC_CMD_XPM_WRITE_BYTES_OUT msgresponse */
+#define MC_CMD_XPM_WRITE_BYTES_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_READ_SECTOR
+ * Read XPM sector
+ */
+#define MC_CMD_XPM_READ_SECTOR 0x105
+#undef MC_CMD_0x105_PRIVILEGE_CTG
+
+#define MC_CMD_0x105_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_READ_SECTOR_IN msgrequest */
+#define MC_CMD_XPM_READ_SECTOR_IN_LEN 8
+/* Sector index */
+#define MC_CMD_XPM_READ_SECTOR_IN_INDEX_OFST 0
+/* Sector size */
+#define MC_CMD_XPM_READ_SECTOR_IN_SIZE_OFST 4
+
+/* MC_CMD_XPM_READ_SECTOR_OUT msgresponse */
+#define MC_CMD_XPM_READ_SECTOR_OUT_LENMIN 4
+#define MC_CMD_XPM_READ_SECTOR_OUT_LENMAX 36
+#define MC_CMD_XPM_READ_SECTOR_OUT_LEN(num) (4+1*(num))
+/* Sector type */
+#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_OFST 0
+#define MC_CMD_XPM_READ_SECTOR_OUT_BLANK 0x0 /* enum */
+#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_128 0x1 /* enum */
+#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_256 0x2 /* enum */
+#define MC_CMD_XPM_READ_SECTOR_OUT_INVALID 0xff /* enum */
+/* Sector data */
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_OFST 4
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_LEN 1
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_MINNUM 0
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_MAXNUM 32
+
+
+/***********************************/
+/* MC_CMD_XPM_WRITE_SECTOR
+ * Write XPM sector
+ */
+#define MC_CMD_XPM_WRITE_SECTOR 0x106
+#undef MC_CMD_0x106_PRIVILEGE_CTG
+
+#define MC_CMD_0x106_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_WRITE_SECTOR_IN msgrequest */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_LENMIN 12
+#define MC_CMD_XPM_WRITE_SECTOR_IN_LENMAX 44
+#define MC_CMD_XPM_WRITE_SECTOR_IN_LEN(num) (12+1*(num))
+/* If writing fails due to an uncorrectable error, try up to RETRIES following
+ * sectors (or until no more space available). If 0, only one write attempt is
+ * made. Note that uncorrectable errors are unlikely, thanks to XPM self-repair
+ * mechanism.
+ */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_RETRIES_OFST 0
+#define MC_CMD_XPM_WRITE_SECTOR_IN_RETRIES_LEN 1
+#define MC_CMD_XPM_WRITE_SECTOR_IN_RESERVED_OFST 1
+#define MC_CMD_XPM_WRITE_SECTOR_IN_RESERVED_LEN 3
+/* Sector type */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_TYPE_OFST 4
+/* Enum values, see field(s): */
+/* MC_CMD_XPM_READ_SECTOR_OUT/TYPE */
+/* Sector size */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_SIZE_OFST 8
+/* Sector data */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_OFST 12
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_LEN 1
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_MINNUM 0
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_MAXNUM 32
+
+/* MC_CMD_XPM_WRITE_SECTOR_OUT msgresponse */
+#define MC_CMD_XPM_WRITE_SECTOR_OUT_LEN 4
+/* New sector index */
+#define MC_CMD_XPM_WRITE_SECTOR_OUT_INDEX_OFST 0
+
+
+/***********************************/
+/* MC_CMD_XPM_INVALIDATE_SECTOR
+ * Invalidate XPM sector
+ */
+#define MC_CMD_XPM_INVALIDATE_SECTOR 0x107
+#undef MC_CMD_0x107_PRIVILEGE_CTG
+
+#define MC_CMD_0x107_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_INVALIDATE_SECTOR_IN msgrequest */
+#define MC_CMD_XPM_INVALIDATE_SECTOR_IN_LEN 4
+/* Sector index */
+#define MC_CMD_XPM_INVALIDATE_SECTOR_IN_INDEX_OFST 0
+
+/* MC_CMD_XPM_INVALIDATE_SECTOR_OUT msgresponse */
+#define MC_CMD_XPM_INVALIDATE_SECTOR_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_BLANK_CHECK
+ * Blank-check XPM memory and report bad locations
+ */
+#define MC_CMD_XPM_BLANK_CHECK 0x108
+#undef MC_CMD_0x108_PRIVILEGE_CTG
+
+#define MC_CMD_0x108_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_BLANK_CHECK_IN msgrequest */
+#define MC_CMD_XPM_BLANK_CHECK_IN_LEN 8
+/* Start address (byte) */
+#define MC_CMD_XPM_BLANK_CHECK_IN_ADDR_OFST 0
+/* Count (bytes) */
+#define MC_CMD_XPM_BLANK_CHECK_IN_COUNT_OFST 4
+
+/* MC_CMD_XPM_BLANK_CHECK_OUT msgresponse */
+#define MC_CMD_XPM_BLANK_CHECK_OUT_LENMIN 4
+#define MC_CMD_XPM_BLANK_CHECK_OUT_LENMAX 252
+#define MC_CMD_XPM_BLANK_CHECK_OUT_LEN(num) (4+2*(num))
+/* Total number of bad (non-blank) locations */
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_COUNT_OFST 0
+/* Addresses of bad locations (may be less than BAD_COUNT, if all cannot fit
+ * into MCDI response)
+ */
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_OFST 4
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_LEN 2
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_MINNUM 0
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_MAXNUM 124
+
+
+/***********************************/
+/* MC_CMD_XPM_REPAIR
+ * Blank-check and repair XPM memory
+ */
+#define MC_CMD_XPM_REPAIR 0x109
+#undef MC_CMD_0x109_PRIVILEGE_CTG
+
+#define MC_CMD_0x109_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_REPAIR_IN msgrequest */
+#define MC_CMD_XPM_REPAIR_IN_LEN 8
+/* Start address (byte) */
+#define MC_CMD_XPM_REPAIR_IN_ADDR_OFST 0
+/* Count (bytes) */
+#define MC_CMD_XPM_REPAIR_IN_COUNT_OFST 4
+
+/* MC_CMD_XPM_REPAIR_OUT msgresponse */
+#define MC_CMD_XPM_REPAIR_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_DECODER_TEST
+ * Test XPM memory address decoders for gross manufacturing defects. Can only
+ * be performed on an unprogrammed part.
+ */
+#define MC_CMD_XPM_DECODER_TEST 0x10a
+#undef MC_CMD_0x10a_PRIVILEGE_CTG
+
+#define MC_CMD_0x10a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_DECODER_TEST_IN msgrequest */
+#define MC_CMD_XPM_DECODER_TEST_IN_LEN 0
+
+/* MC_CMD_XPM_DECODER_TEST_OUT msgresponse */
+#define MC_CMD_XPM_DECODER_TEST_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_WRITE_TEST
+ * XPM memory write test. Test XPM write logic for gross manufacturing defects
+ * by writing to a dedicated test row. There are 16 locations in the test row
+ * and the test can only be performed on locations that have not been
+ * previously used (i.e. can be run at most 16 times). The test will pick the
+ * first available location to use, or fail with ENOSPC if none left.
+ */
+#define MC_CMD_XPM_WRITE_TEST 0x10b
+#undef MC_CMD_0x10b_PRIVILEGE_CTG
+
+#define MC_CMD_0x10b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_WRITE_TEST_IN msgrequest */
+#define MC_CMD_XPM_WRITE_TEST_IN_LEN 0
+
+/* MC_CMD_XPM_WRITE_TEST_OUT msgresponse */
+#define MC_CMD_XPM_WRITE_TEST_OUT_LEN 0
+
#endif /* _SIENA_MC_DRIVER_PCOL_H */
diff --git a/sys/dev/sfxge/common/efx_regs_pci.h b/sys/dev/sfxge/common/efx_regs_pci.h
index 3a3a8273e22c..a5fd45b6739c 100644
--- a/sys/dev/sfxge/common/efx_regs_pci.h
+++ b/sys/dev/sfxge/common/efx_regs_pci.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2010 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -366,6 +371,10 @@ extern "C" {
#define PCRF_AZ_INT_PIN_LBN 0
#define PCRF_AZ_INT_PIN_WIDTH 8
+#define PCFE_DZ_INTPIN_INTD 4
+#define PCFE_DZ_INTPIN_INTC 3
+#define PCFE_DZ_INTPIN_INTB 2
+#define PCFE_DZ_INTPIN_INTA 1
/*
@@ -373,11 +382,8 @@ extern "C" {
* Power management capability ID
*/
-#define PCR_AC_PM_CAP_ID_REG 0x00000040
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_PM_CAP_ID_REG 0x00000080
-/* hunta0=pci_f0_config */
+#define PCR_AZ_PM_CAP_ID_REG 0x00000040
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PM_CAP_ID_LBN 0
#define PCRF_AZ_PM_CAP_ID_WIDTH 8
@@ -388,11 +394,8 @@ extern "C" {
* Power management next item pointer
*/
-#define PCR_AC_PM_NXT_PTR_REG 0x00000041
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_PM_NXT_PTR_REG 0x00000081
-/* hunta0=pci_f0_config */
+#define PCR_AZ_PM_NXT_PTR_REG 0x00000041
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PM_NXT_PTR_LBN 0
#define PCRF_AZ_PM_NXT_PTR_WIDTH 8
@@ -403,11 +406,8 @@ extern "C" {
* Power management capabilities register
*/
-#define PCR_AC_PM_CAP_REG 0x00000042
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_PM_CAP_REG 0x00000082
-/* hunta0=pci_f0_config */
+#define PCR_AZ_PM_CAP_REG 0x00000042
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PM_PME_SUPT_LBN 11
#define PCRF_AZ_PM_PME_SUPT_WIDTH 5
@@ -430,11 +430,8 @@ extern "C" {
* Power management control & status register
*/
-#define PCR_AC_PM_CS_REG 0x00000044
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_PM_CS_REG 0x00000084
-/* hunta0=pci_f0_config */
+#define PCR_AZ_PM_CS_REG 0x00000044
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PM_PME_STAT_LBN 15
#define PCRF_AZ_PM_PME_STAT_WIDTH 1
@@ -455,11 +452,8 @@ extern "C" {
* MSI capability ID
*/
-#define PCR_AC_MSI_CAP_ID_REG 0x00000050
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_CAP_ID_REG 0x00000090
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_CAP_ID_REG 0x00000050
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_CAP_ID_LBN 0
#define PCRF_AZ_MSI_CAP_ID_WIDTH 8
@@ -470,11 +464,8 @@ extern "C" {
* MSI next item pointer
*/
-#define PCR_AC_MSI_NXT_PTR_REG 0x00000051
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_NXT_PTR_REG 0x00000091
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_NXT_PTR_REG 0x00000051
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_NXT_PTR_LBN 0
#define PCRF_AZ_MSI_NXT_PTR_WIDTH 8
@@ -485,11 +476,8 @@ extern "C" {
* MSI control register
*/
-#define PCR_AC_MSI_CTL_REG 0x00000052
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_CTL_REG 0x00000092
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_CTL_REG 0x00000052
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_64_EN_LBN 7
#define PCRF_AZ_MSI_64_EN_WIDTH 1
@@ -506,65 +494,20 @@ extern "C" {
* MSI low 32 bits address register
*/
-#define PCR_AC_MSI_ADR_LO_REG 0x00000054
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_ADR_LO_REG 0x00000094
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_ADR_LO_REG 0x00000054
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_ADR_LO_LBN 2
#define PCRF_AZ_MSI_ADR_LO_WIDTH 30
/*
- * PC_VPD_CAP_CTL_REG(8bit):
- * VPD control and capabilities register
- */
-
-#define PCR_DZ_VPD_CAP_CTL_REG 0x00000054
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_VPD_CAP_CTL_REG 0x000000d0
-/* sienaa0=pci_f0_config */
-
-#define PCRF_CZ_VPD_FLAG_LBN 31
-#define PCRF_CZ_VPD_FLAG_WIDTH 1
-#define PCRF_CZ_VPD_ADDR_LBN 16
-#define PCRF_CZ_VPD_ADDR_WIDTH 15
-#define PCRF_CZ_VPD_NXT_PTR_LBN 8
-#define PCRF_CZ_VPD_NXT_PTR_WIDTH 8
-#define PCRF_CZ_VPD_CAP_ID_LBN 0
-#define PCRF_CZ_VPD_CAP_ID_WIDTH 8
-
-
-/*
- * PC_VPD_CAP_DATA_REG(32bit):
- * documentation to be written for sum_PC_VPD_CAP_DATA_REG
- */
-
-#define PCR_DZ_VPD_CAP_DATA_REG 0x00000058
-/* hunta0=pci_f0_config */
-
-#define PCR_AB_VPD_CAP_DATA_REG 0x000000b4
-/* falcona0,falconb0=pci_f0_config */
-
-#define PCR_CC_VPD_CAP_DATA_REG 0x000000d4
-/* sienaa0=pci_f0_config */
-
-#define PCRF_AZ_VPD_DATA_LBN 0
-#define PCRF_AZ_VPD_DATA_WIDTH 32
-
-
-/*
* PC_MSI_ADR_HI_REG(32bit):
* MSI high 32 bits address register
*/
-#define PCR_AC_MSI_ADR_HI_REG 0x00000058
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_ADR_HI_REG 0x00000098
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_ADR_HI_REG 0x00000058
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_ADR_HI_LBN 0
#define PCRF_AZ_MSI_ADR_HI_WIDTH 32
@@ -575,11 +518,8 @@ extern "C" {
* MSI data register
*/
-#define PCR_AC_MSI_DAT_REG 0x0000005c
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_DAT_REG 0x0000009c
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_DAT_REG 0x0000005c
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_DAT_LBN 0
#define PCRF_AZ_MSI_DAT_WIDTH 16
@@ -593,11 +533,8 @@ extern "C" {
#define PCR_AB_PCIE_CAP_LIST_REG 0x00000060
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_PCIE_CAP_LIST_REG 0x00000070
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_PCIE_CAP_LIST_REG 0x000000c0
-/* hunta0=pci_f0_config */
+#define PCR_CZ_PCIE_CAP_LIST_REG 0x00000070
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PCIE_NXT_PTR_LBN 8
#define PCRF_AZ_PCIE_NXT_PTR_WIDTH 8
@@ -613,11 +550,8 @@ extern "C" {
#define PCR_AB_PCIE_CAP_REG 0x00000062
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_PCIE_CAP_REG 0x00000072
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_PCIE_CAP_REG 0x000000c2
-/* hunta0=pci_f0_config */
+#define PCR_CZ_PCIE_CAP_REG 0x00000072
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PCIE_INT_MSG_NUM_LBN 9
#define PCRF_AZ_PCIE_INT_MSG_NUM_WIDTH 5
@@ -637,11 +571,8 @@ extern "C" {
#define PCR_AB_DEV_CAP_REG 0x00000064
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_DEV_CAP_REG 0x00000074
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_DEV_CAP_REG 0x000000c4
-/* hunta0=pci_f0_config */
+#define PCR_CZ_DEV_CAP_REG 0x00000074
+/* sienaa0=pci_f0_config,hunta0=pci_f0_config */
#define PCRF_CZ_CAP_FN_LEVEL_RESET_LBN 28
#define PCRF_CZ_CAP_FN_LEVEL_RESET_WIDTH 1
@@ -677,11 +608,8 @@ extern "C" {
#define PCR_AB_DEV_CTL_REG 0x00000068
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_DEV_CTL_REG 0x00000078
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_DEV_CTL_REG 0x000000c8
-/* hunta0=pci_f0_config */
+#define PCR_CZ_DEV_CTL_REG 0x00000078
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_FN_LEVEL_RESET_LBN 15
#define PCRF_CZ_FN_LEVEL_RESET_WIDTH 1
@@ -693,7 +621,6 @@ extern "C" {
#define PCFE_AZ_MAX_RD_REQ_SIZE_512 2
#define PCFE_AZ_MAX_RD_REQ_SIZE_256 1
#define PCFE_AZ_MAX_RD_REQ_SIZE_128 0
-#define PCFE_DZ_OTHER other
#define PCRF_AZ_EN_NO_SNOOP_LBN 11
#define PCRF_AZ_EN_NO_SNOOP_WIDTH 1
#define PCRF_AZ_AUX_PWR_PM_EN_LBN 10
@@ -712,7 +639,6 @@ extern "C" {
#define PCFE_AZ_MAX_PAYL_SIZE_512 2
#define PCFE_AZ_MAX_PAYL_SIZE_256 1
#define PCFE_AZ_MAX_PAYL_SIZE_128 0
-#define PCFE_DZ_OTHER other
#define PCRF_AZ_EN_RELAX_ORDER_LBN 4
#define PCRF_AZ_EN_RELAX_ORDER_WIDTH 1
#define PCRF_AZ_UNSUP_REQ_RPT_EN_LBN 3
@@ -733,11 +659,8 @@ extern "C" {
#define PCR_AB_DEV_STAT_REG 0x0000006a
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_DEV_STAT_REG 0x0000007a
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_DEV_STAT_REG 0x000000ca
-/* hunta0=pci_f0_config */
+#define PCR_CZ_DEV_STAT_REG 0x0000007a
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_TRNS_PEND_LBN 5
#define PCRF_AZ_TRNS_PEND_WIDTH 1
@@ -761,14 +684,13 @@ extern "C" {
#define PCR_AB_LNK_CAP_REG 0x0000006c
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_LNK_CAP_REG 0x0000007c
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_CAP_REG 0x000000cc
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_CAP_REG 0x0000007c
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PORT_NUM_LBN 24
#define PCRF_AZ_PORT_NUM_WIDTH 8
+#define PCRF_DZ_ASPM_OPTIONALITY_CAP_LBN 22
+#define PCRF_DZ_ASPM_OPTIONALITY_CAP_WIDTH 1
#define PCRF_CZ_LINK_BWDITH_NOTIF_CAP_LBN 21
#define PCRF_CZ_LINK_BWDITH_NOTIF_CAP_WIDTH 1
#define PCRF_CZ_DATA_LINK_ACTIVE_RPT_CAP_LBN 20
@@ -797,11 +719,8 @@ extern "C" {
#define PCR_AB_LNK_CTL_REG 0x00000070
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_LNK_CTL_REG 0x00000080
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_CTL_REG 0x000000d0
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_CTL_REG 0x00000080
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_EXT_SYNC_LBN 7
#define PCRF_AZ_EXT_SYNC_WIDTH 1
@@ -827,11 +746,8 @@ extern "C" {
#define PCR_AB_LNK_STAT_REG 0x00000072
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_LNK_STAT_REG 0x00000082
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_STAT_REG 0x000000d2
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_STAT_REG 0x00000082
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_SLOT_CLK_CFG_LBN 12
#define PCRF_AZ_SLOT_CLK_CFG_WIDTH 1
@@ -977,18 +893,40 @@ extern "C" {
/*
- * PC_DEV_CAP2_REG(16bit):
- * PCIe Device Capabilities 2
+ * PC_MSIX_TBL_BASE_REG(32bit):
+ * MSIX Capability Vector Table Base
*/
-#define PCR_CC_DEV_CAP2_REG 0x00000094
-/* sienaa0=pci_f0_config */
+#define PCR_BB_MSIX_TBL_BASE_REG 0x00000094
+/* falconb0=pci_f0_config */
-#define PCR_DZ_DEV_CAP2_REG 0x000000e4
-/* hunta0=pci_f0_config */
+#define PCR_CZ_MSIX_TBL_BASE_REG 0x000000b4
+/* sienaa0,hunta0=pci_f0_config */
-#define PCRF_CZ_CMPL_TIMEOUT_DIS_LBN 4
-#define PCRF_CZ_CMPL_TIMEOUT_DIS_WIDTH 1
+#define PCRF_BZ_MSIX_TBL_OFF_LBN 3
+#define PCRF_BZ_MSIX_TBL_OFF_WIDTH 29
+#define PCRF_BZ_MSIX_TBL_BIR_LBN 0
+#define PCRF_BZ_MSIX_TBL_BIR_WIDTH 3
+
+
+/*
+ * PC_DEV_CAP2_REG(32bit):
+ * PCIe Device Capabilities 2
+ */
+
+#define PCR_CZ_DEV_CAP2_REG 0x00000094
+/* sienaa0=pci_f0_config,hunta0=pci_f0_config */
+
+#define PCRF_DZ_OBFF_SUPPORTED_LBN 18
+#define PCRF_DZ_OBFF_SUPPORTED_WIDTH 2
+#define PCRF_DZ_TPH_CMPL_SUPPORTED_LBN 12
+#define PCRF_DZ_TPH_CMPL_SUPPORTED_WIDTH 2
+#define PCRF_DZ_LTR_M_SUPPORTED_LBN 11
+#define PCRF_DZ_LTR_M_SUPPORTED_WIDTH 1
+#define PCRF_CC_CMPL_TIMEOUT_DIS_LBN 4
+#define PCRF_CC_CMPL_TIMEOUT_DIS_WIDTH 1
+#define PCRF_DZ_CMPL_TIMEOUT_DIS_SUPPORTED_LBN 4
+#define PCRF_DZ_CMPL_TIMEOUT_DIS_SUPPORTED_WIDTH 1
#define PCRF_CZ_CMPL_TIMEOUT_LBN 0
#define PCRF_CZ_CMPL_TIMEOUT_WIDTH 4
#define PCFE_CZ_CMPL_TIMEOUT_17000_TO_6400MS 14
@@ -1003,33 +941,21 @@ extern "C" {
/*
- * PC_MSIX_TBL_BASE_REG(32bit):
- * MSIX Capability Vector Table Base
- */
-
-#define PCR_BB_MSIX_TBL_BASE_REG 0x00000094
-/* falconb0=pci_f0_config */
-
-#define PCR_CZ_MSIX_TBL_BASE_REG 0x000000b4
-/* sienaa0,hunta0=pci_f0_config */
-
-#define PCRF_BZ_MSIX_TBL_OFF_LBN 3
-#define PCRF_BZ_MSIX_TBL_OFF_WIDTH 29
-#define PCRF_BZ_MSIX_TBL_BIR_LBN 0
-#define PCRF_BZ_MSIX_TBL_BIR_WIDTH 3
-
-
-/*
* PC_DEV_CTL2_REG(16bit):
* PCIe Device Control 2
*/
-#define PCR_CC_DEV_CTL2_REG 0x00000098
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_DEV_CTL2_REG 0x000000e8
-/* hunta0=pci_f0_config */
+#define PCR_CZ_DEV_CTL2_REG 0x00000098
+/* sienaa0,hunta0=pci_f0_config */
+#define PCRF_DZ_OBFF_ENABLE_LBN 13
+#define PCRF_DZ_OBFF_ENABLE_WIDTH 2
+#define PCRF_DZ_LTR_ENABLE_LBN 10
+#define PCRF_DZ_LTR_ENABLE_WIDTH 1
+#define PCRF_DZ_IDO_COMPLETION_ENABLE_LBN 9
+#define PCRF_DZ_IDO_COMPLETION_ENABLE_WIDTH 1
+#define PCRF_DZ_IDO_REQUEST_ENABLE_LBN 8
+#define PCRF_DZ_IDO_REQUEST_ENABLE_WIDTH 1
#define PCRF_CZ_CMPL_TIMEOUT_DIS_CTL_LBN 4
#define PCRF_CZ_CMPL_TIMEOUT_DIS_CTL_WIDTH 1
#define PCRF_CZ_CMPL_TIMEOUT_CTL_LBN 0
@@ -1054,15 +980,24 @@ extern "C" {
/*
+ * PC_LNK_CAP2_REG(32bit):
+ * PCIe Link Capability 2
+ */
+
+#define PCR_DZ_LNK_CAP2_REG 0x0000009c
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LNK_SPEED_SUP_LBN 1
+#define PCRF_DZ_LNK_SPEED_SUP_WIDTH 7
+
+
+/*
* PC_LNK_CTL2_REG(16bit):
* PCIe Link Control 2
*/
-#define PCR_CC_LNK_CTL2_REG 0x000000a0
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_CTL2_REG 0x000000f0
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_CTL2_REG 0x000000a0
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_POLLING_DEEMPH_LVL_LBN 12
#define PCRF_CZ_POLLING_DEEMPH_LVL_WIDTH 1
@@ -1080,6 +1015,9 @@ extern "C" {
#define PCRF_CZ_ENTER_COMPLIANCE_CTL_WIDTH 1
#define PCRF_CZ_TGT_LNK_SPEED_CTL_LBN 0
#define PCRF_CZ_TGT_LNK_SPEED_CTL_WIDTH 4
+#define PCFE_DZ_LCTL2_TGT_SPEED_GEN3 3
+#define PCFE_DZ_LCTL2_TGT_SPEED_GEN2 2
+#define PCFE_DZ_LCTL2_TGT_SPEED_GEN1 1
/*
@@ -1087,11 +1025,8 @@ extern "C" {
* PCIe Link Status 2
*/
-#define PCR_CC_LNK_STAT2_REG 0x000000a2
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_STAT2_REG 0x000000f2
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_STAT2_REG 0x000000a2
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_CURRENT_DEEMPH_LBN 0
#define PCRF_CZ_CURRENT_DEEMPH_WIDTH 1
@@ -1136,6 +1071,39 @@ extern "C" {
/*
+ * PC_VPD_CAP_DATA_REG(32bit):
+ * documentation to be written for sum_PC_VPD_CAP_DATA_REG
+ */
+
+#define PCR_AB_VPD_CAP_DATA_REG 0x000000b4
+/* falcona0,falconb0=pci_f0_config */
+
+#define PCR_CZ_VPD_CAP_DATA_REG 0x000000d4
+/* sienaa0,hunta0=pci_f0_config */
+
+#define PCRF_AZ_VPD_DATA_LBN 0
+#define PCRF_AZ_VPD_DATA_WIDTH 32
+
+
+/*
+ * PC_VPD_CAP_CTL_REG(8bit):
+ * VPD control and capabilities register
+ */
+
+#define PCR_CZ_VPD_CAP_CTL_REG 0x000000d0
+/* sienaa0,hunta0=pci_f0_config */
+
+#define PCRF_CZ_VPD_FLAG_LBN 31
+#define PCRF_CZ_VPD_FLAG_WIDTH 1
+#define PCRF_CZ_VPD_ADDR_LBN 16
+#define PCRF_CZ_VPD_ADDR_WIDTH 15
+#define PCRF_CZ_VPD_NXT_PTR_LBN 8
+#define PCRF_CZ_VPD_NXT_PTR_WIDTH 8
+#define PCRF_CZ_VPD_CAP_ID_LBN 0
+#define PCRF_CZ_VPD_CAP_ID_WIDTH 8
+
+
+/*
* PC_AER_CAP_HDR_REG(32bit):
* AER capability header register
*/
@@ -1191,6 +1159,10 @@ extern "C" {
#define PCR_AZ_AER_UNCORR_ERR_MASK_REG 0x00000108
/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
+#define PCRF_DZ_ATOMIC_OP_EGR_BLOCKED_MASK_LBN 24
+#define PCRF_DZ_ATOMIC_OP_EGR_BLOCKED_MASK_WIDTH 1
+#define PCRF_DZ_UNCORR_INT_ERR_MASK_LBN 22
+#define PCRF_DZ_UNCORR_INT_ERR_MASK_WIDTH 1
#define PCRF_AZ_UNSUPT_REQ_ERR_MASK_LBN 20
#define PCRF_AZ_UNSUPT_REQ_ERR_MASK_WIDTH 1
#define PCRF_AZ_ECRC_ERR_MASK_LBN 19
@@ -1328,11 +1300,8 @@ extern "C" {
* Device serial number capability header register
*/
-#define PCR_DZ_DEVSN_CAP_HDR_REG 0x00000130
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_DEVSN_CAP_HDR_REG 0x00000140
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_DEVSN_CAP_HDR_REG 0x00000140
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_DEVSNCAPHDR_NXT_PTR_LBN 20
#define PCRF_CZ_DEVSNCAPHDR_NXT_PTR_WIDTH 12
@@ -1347,11 +1316,8 @@ extern "C" {
* Device serial number DWORD0
*/
-#define PCR_DZ_DEVSN_DWORD0_REG 0x00000134
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_DEVSN_DWORD0_REG 0x00000144
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_DEVSN_DWORD0_REG 0x00000144
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_DEVSN_DWORD0_LBN 0
#define PCRF_CZ_DEVSN_DWORD0_WIDTH 32
@@ -1362,11 +1328,8 @@ extern "C" {
* Device serial number DWORD0
*/
-#define PCR_DZ_DEVSN_DWORD1_REG 0x00000138
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_DEVSN_DWORD1_REG 0x00000148
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_DEVSN_DWORD1_REG 0x00000148
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_DEVSN_DWORD1_LBN 0
#define PCRF_CZ_DEVSN_DWORD1_WIDTH 32
@@ -1377,11 +1340,8 @@ extern "C" {
* ARI capability header register
*/
-#define PCR_DZ_ARI_CAP_HDR_REG 0x00000140
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_ARI_CAP_HDR_REG 0x00000150
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_ARI_CAP_HDR_REG 0x00000150
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_ARICAPHDR_NXT_PTR_LBN 20
#define PCRF_CZ_ARICAPHDR_NXT_PTR_WIDTH 12
@@ -1396,11 +1356,8 @@ extern "C" {
* ARI Capabilities
*/
-#define PCR_DZ_ARI_CAP_REG 0x00000144
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_ARI_CAP_REG 0x00000154
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_ARI_CAP_REG 0x00000154
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_ARI_NXT_FN_NUM_LBN 8
#define PCRF_CZ_ARI_NXT_FN_NUM_WIDTH 8
@@ -1415,11 +1372,8 @@ extern "C" {
* ARI Control
*/
-#define PCR_DZ_ARI_CTL_REG 0x00000146
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_ARI_CTL_REG 0x00000156
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_ARI_CTL_REG 0x00000156
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_ARI_FN_GRP_LBN 4
#define PCRF_CZ_ARI_FN_GRP_WIDTH 3
@@ -1430,6 +1384,22 @@ extern "C" {
/*
+ * PC_SEC_PCIE_CAP_REG(32bit):
+ * Secondary PCIE Capability Register
+ */
+
+#define PCR_DZ_SEC_PCIE_CAP_REG 0x00000160
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_SEC_NXT_PTR_LBN 20
+#define PCRF_DZ_SEC_NXT_PTR_WIDTH 12
+#define PCRF_DZ_SEC_VERSION_LBN 16
+#define PCRF_DZ_SEC_VERSION_WIDTH 4
+#define PCRF_DZ_SEC_EXT_CAP_ID_LBN 0
+#define PCRF_DZ_SEC_EXT_CAP_ID_WIDTH 16
+
+
+/*
* PC_SRIOV_CAP_HDR_REG(32bit):
* SRIOV capability header register
*/
@@ -1437,7 +1407,7 @@ extern "C" {
#define PCR_CC_SRIOV_CAP_HDR_REG 0x00000160
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_CAP_HDR_REG 0x00000200
+#define PCR_DZ_SRIOV_CAP_HDR_REG 0x00000180
/* hunta0=pci_f0_config */
#define PCRF_CZ_SRIOVCAPHDR_NXT_PTR_LBN 20
@@ -1456,16 +1426,44 @@ extern "C" {
#define PCR_CC_SRIOV_CAP_REG 0x00000164
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_CAP_REG 0x00000204
+#define PCR_DZ_SRIOV_CAP_REG 0x00000184
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_MIGR_INT_MSG_NUM_LBN 21
#define PCRF_CZ_VF_MIGR_INT_MSG_NUM_WIDTH 11
+#define PCRF_DZ_VF_ARI_CAP_PRESV_LBN 1
+#define PCRF_DZ_VF_ARI_CAP_PRESV_WIDTH 1
#define PCRF_CZ_VF_MIGR_CAP_LBN 0
#define PCRF_CZ_VF_MIGR_CAP_WIDTH 1
/*
+ * PC_LINK_CONTROL3_REG(32bit):
+ * Link Control 3.
+ */
+
+#define PCR_DZ_LINK_CONTROL3_REG 0x00000164
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LINK_EQ_INT_EN_LBN 1
+#define PCRF_DZ_LINK_EQ_INT_EN_WIDTH 1
+#define PCRF_DZ_PERFORM_EQL_LBN 0
+#define PCRF_DZ_PERFORM_EQL_WIDTH 1
+
+
+/*
+ * PC_LANE_ERROR_STAT_REG(32bit):
+ * Lane Error Status Register.
+ */
+
+#define PCR_DZ_LANE_ERROR_STAT_REG 0x00000168
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE_STATUS_LBN 0
+#define PCRF_DZ_LANE_STATUS_WIDTH 8
+
+
+/*
* PC_SRIOV_CTL_REG(16bit):
* SRIOV Control
*/
@@ -1473,7 +1471,7 @@ extern "C" {
#define PCR_CC_SRIOV_CTL_REG 0x00000168
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_CTL_REG 0x00000208
+#define PCR_DZ_SRIOV_CTL_REG 0x00000188
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_ARI_CAP_HRCHY_LBN 4
@@ -1496,7 +1494,7 @@ extern "C" {
#define PCR_CC_SRIOV_STAT_REG 0x0000016a
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_STAT_REG 0x0000020a
+#define PCR_DZ_SRIOV_STAT_REG 0x0000018a
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_MIGR_STAT_LBN 0
@@ -1504,6 +1502,20 @@ extern "C" {
/*
+ * PC_LANE01_EQU_CONTROL_REG(32bit):
+ * Lanes 0,1 Equalization Control Register.
+ */
+
+#define PCR_DZ_LANE01_EQU_CONTROL_REG 0x0000016c
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE1_EQ_CTRL_LBN 16
+#define PCRF_DZ_LANE1_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LANE0_EQ_CTRL_LBN 0
+#define PCRF_DZ_LANE0_EQ_CTRL_WIDTH 16
+
+
+/*
* PC_SRIOV_INITIALVFS_REG(16bit):
* SRIOV Initial VFs
*/
@@ -1511,7 +1523,7 @@ extern "C" {
#define PCR_CC_SRIOV_INITIALVFS_REG 0x0000016c
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_INITIALVFS_REG 0x0000020c
+#define PCR_DZ_SRIOV_INITIALVFS_REG 0x0000018c
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_INITIALVFS_LBN 0
@@ -1526,7 +1538,7 @@ extern "C" {
#define PCR_CC_SRIOV_TOTALVFS_REG 0x0000016e
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_TOTALVFS_REG 0x0000020e
+#define PCR_DZ_SRIOV_TOTALVFS_REG 0x0000018e
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_TOTALVFS_LBN 0
@@ -1541,7 +1553,7 @@ extern "C" {
#define PCR_CC_SRIOV_NUMVFS_REG 0x00000170
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_NUMVFS_REG 0x00000210
+#define PCR_DZ_SRIOV_NUMVFS_REG 0x00000190
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_NUMVFS_LBN 0
@@ -1549,6 +1561,20 @@ extern "C" {
/*
+ * PC_LANE23_EQU_CONTROL_REG(32bit):
+ * Lanes 2,3 Equalization Control Register.
+ */
+
+#define PCR_DZ_LANE23_EQU_CONTROL_REG 0x00000170
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE3_EQ_CTRL_LBN 16
+#define PCRF_DZ_LANE3_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LANE2_EQ_CTRL_LBN 0
+#define PCRF_DZ_LANE2_EQ_CTRL_WIDTH 16
+
+
+/*
* PC_SRIOV_FN_DPND_LNK_REG(16bit):
* SRIOV Function dependency link
*/
@@ -1556,7 +1582,7 @@ extern "C" {
#define PCR_CC_SRIOV_FN_DPND_LNK_REG 0x00000172
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_FN_DPND_LNK_REG 0x00000212
+#define PCR_DZ_SRIOV_FN_DPND_LNK_REG 0x00000192
/* hunta0=pci_f0_config */
#define PCRF_CZ_SRIOV_FN_DPND_LNK_LBN 0
@@ -1571,7 +1597,7 @@ extern "C" {
#define PCR_CC_SRIOV_1STVF_OFFSET_REG 0x00000174
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_1STVF_OFFSET_REG 0x00000214
+#define PCR_DZ_SRIOV_1STVF_OFFSET_REG 0x00000194
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_1STVF_OFFSET_LBN 0
@@ -1579,6 +1605,20 @@ extern "C" {
/*
+ * PC_LANE45_EQU_CONTROL_REG(32bit):
+ * Lanes 4,5 Equalization Control Register.
+ */
+
+#define PCR_DZ_LANE45_EQU_CONTROL_REG 0x00000174
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE5_EQ_CTRL_LBN 16
+#define PCRF_DZ_LANE5_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LANE4_EQ_CTRL_LBN 0
+#define PCRF_DZ_LANE4_EQ_CTRL_WIDTH 16
+
+
+/*
* PC_SRIOV_VFSTRIDE_REG(16bit):
* SRIOV VF Stride
*/
@@ -1586,7 +1626,7 @@ extern "C" {
#define PCR_CC_SRIOV_VFSTRIDE_REG 0x00000176
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_VFSTRIDE_REG 0x00000216
+#define PCR_DZ_SRIOV_VFSTRIDE_REG 0x00000196
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_VFSTRIDE_LBN 0
@@ -1594,6 +1634,20 @@ extern "C" {
/*
+ * PC_LANE67_EQU_CONTROL_REG(32bit):
+ * Lanes 6,7 Equalization Control Register.
+ */
+
+#define PCR_DZ_LANE67_EQU_CONTROL_REG 0x00000178
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE7_EQ_CTRL_LBN 16
+#define PCRF_DZ_LANE7_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LANE6_EQ_CTRL_LBN 0
+#define PCRF_DZ_LANE6_EQ_CTRL_WIDTH 16
+
+
+/*
* PC_SRIOV_DEVID_REG(16bit):
* SRIOV VF Device ID
*/
@@ -1601,7 +1655,7 @@ extern "C" {
#define PCR_CC_SRIOV_DEVID_REG 0x0000017a
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_DEVID_REG 0x0000021a
+#define PCR_DZ_SRIOV_DEVID_REG 0x0000019a
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_DEVID_LBN 0
@@ -1616,7 +1670,7 @@ extern "C" {
#define PCR_CC_SRIOV_SUP_PAGESZ_REG 0x0000017c
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_SUP_PAGESZ_REG 0x0000021c
+#define PCR_DZ_SRIOV_SUP_PAGESZ_REG 0x0000019c
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_SUP_PAGESZ_LBN 0
@@ -1631,7 +1685,7 @@ extern "C" {
#define PCR_CC_SRIOV_SYS_PAGESZ_REG 0x00000180
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_SYS_PAGESZ_REG 0x00000220
+#define PCR_DZ_SRIOV_SYS_PAGESZ_REG 0x000001a0
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_SYS_PAGESZ_LBN 0
@@ -1646,13 +1700,19 @@ extern "C" {
#define PCR_CC_SRIOV_BAR0_REG 0x00000184
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR0_REG 0x00000224
+#define PCR_DZ_SRIOV_BAR0_REG 0x000001a4
/* hunta0=pci_f0_config */
#define PCRF_CC_VF_BAR_ADDRESS_LBN 0
#define PCRF_CC_VF_BAR_ADDRESS_WIDTH 32
-#define PCRF_DZ_VF_BAR0_ADDRESS_LBN 0
-#define PCRF_DZ_VF_BAR0_ADDRESS_WIDTH 32
+#define PCRF_DZ_VF_BAR0_ADDRESS_LBN 4
+#define PCRF_DZ_VF_BAR0_ADDRESS_WIDTH 28
+#define PCRF_DZ_VF_BAR0_PREF_LBN 3
+#define PCRF_DZ_VF_BAR0_PREF_WIDTH 1
+#define PCRF_DZ_VF_BAR0_TYPE_LBN 1
+#define PCRF_DZ_VF_BAR0_TYPE_WIDTH 2
+#define PCRF_DZ_VF_BAR0_IOM_LBN 0
+#define PCRF_DZ_VF_BAR0_IOM_WIDTH 1
/*
@@ -1663,7 +1723,7 @@ extern "C" {
#define PCR_CC_SRIOV_BAR1_REG 0x00000188
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR1_REG 0x00000228
+#define PCR_DZ_SRIOV_BAR1_REG 0x000001a8
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
@@ -1680,13 +1740,19 @@ extern "C" {
#define PCR_CC_SRIOV_BAR2_REG 0x0000018c
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR2_REG 0x0000022c
+#define PCR_DZ_SRIOV_BAR2_REG 0x000001ac
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
/* defined as PCRF_CC_VF_BAR_ADDRESS_WIDTH 32 */
-#define PCRF_DZ_VF_BAR2_ADDRESS_LBN 0
-#define PCRF_DZ_VF_BAR2_ADDRESS_WIDTH 32
+#define PCRF_DZ_VF_BAR2_ADDRESS_LBN 4
+#define PCRF_DZ_VF_BAR2_ADDRESS_WIDTH 28
+#define PCRF_DZ_VF_BAR2_PREF_LBN 3
+#define PCRF_DZ_VF_BAR2_PREF_WIDTH 1
+#define PCRF_DZ_VF_BAR2_TYPE_LBN 1
+#define PCRF_DZ_VF_BAR2_TYPE_WIDTH 2
+#define PCRF_DZ_VF_BAR2_IOM_LBN 0
+#define PCRF_DZ_VF_BAR2_IOM_WIDTH 1
/*
@@ -1697,7 +1763,7 @@ extern "C" {
#define PCR_CC_SRIOV_BAR3_REG 0x00000190
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR3_REG 0x00000230
+#define PCR_DZ_SRIOV_BAR3_REG 0x000001b0
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
@@ -1714,7 +1780,7 @@ extern "C" {
#define PCR_CC_SRIOV_BAR4_REG 0x00000194
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR4_REG 0x00000234
+#define PCR_DZ_SRIOV_BAR4_REG 0x000001b4
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
@@ -1731,7 +1797,7 @@ extern "C" {
#define PCR_CC_SRIOV_BAR5_REG 0x00000198
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR5_REG 0x00000238
+#define PCR_DZ_SRIOV_BAR5_REG 0x000001b8
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
@@ -1741,6 +1807,18 @@ extern "C" {
/*
+ * PC_SRIOV_RSVD_REG(16bit):
+ * Reserved register
+ */
+
+#define PCR_DZ_SRIOV_RSVD_REG 0x00000198
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_VF_RSVD_LBN 0
+#define PCRF_DZ_VF_RSVD_WIDTH 16
+
+
+/*
* PC_SRIOV_MIBR_SARRAY_OFFSET_REG(32bit):
* SRIOV VF Migration State Array Offset
*/
@@ -1748,7 +1826,7 @@ extern "C" {
#define PCR_CC_SRIOV_MIBR_SARRAY_OFFSET_REG 0x0000019c
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_MIBR_SARRAY_OFFSET_REG 0x0000023c
+#define PCR_DZ_SRIOV_MIBR_SARRAY_OFFSET_REG 0x000001bc
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_MIGR_OFFSET_LBN 3
@@ -1758,45 +1836,11 @@ extern "C" {
/*
- * PC_LTR_CAP_HDR_REG(32bit):
- * Latency Tolerance Reporting Cap Header Reg
- */
-
-#define PCR_DZ_LTR_CAP_HDR_REG 0x00000240
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LTR_NXT_PTR_LBN 20
-#define PCRF_DZ_LTR_NXT_PTR_WIDTH 12
-#define PCRF_DZ_LTR_VERSION_LBN 16
-#define PCRF_DZ_LTR_VERSION_WIDTH 4
-#define PCRF_DZ_LTR_EXT_CAP_ID_LBN 0
-#define PCRF_DZ_LTR_EXT_CAP_ID_WIDTH 16
-
-
-/*
- * PC_LTR_MAX_SNOOP_REG(32bit):
- * LTR Maximum Snoop/No Snoop Register
- */
-
-#define PCR_DZ_LTR_MAX_SNOOP_REG 0x00000244
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_LBN 26
-#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_WIDTH 3
-#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_LBN 16
-#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_WIDTH 10
-#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_LBN 10
-#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_WIDTH 3
-#define PCRF_DZ_LTR_MAX_SNOOP_LAT_LBN 0
-#define PCRF_DZ_LTR_MAX_SNOOP_LAT_WIDTH 10
-
-
-/*
* PC_TPH_CAP_HDR_REG(32bit):
* TPH Capability Header Register
*/
-#define PCR_DZ_TPH_CAP_HDR_REG 0x00000274
+#define PCR_DZ_TPH_CAP_HDR_REG 0x000001c0
/* hunta0=pci_f0_config */
#define PCRF_DZ_TPH_NXT_PTR_LBN 20
@@ -1812,7 +1856,7 @@ extern "C" {
* TPH Requester Capability Register
*/
-#define PCR_DZ_TPH_REQ_CAP_REG 0x00000278
+#define PCR_DZ_TPH_REQ_CAP_REG 0x000001c4
/* hunta0=pci_f0_config */
#define PCRF_DZ_ST_TBLE_SIZE_LBN 16
@@ -1834,7 +1878,7 @@ extern "C" {
* TPH Requester Control Register
*/
-#define PCR_DZ_TPH_REQ_CTL_REG 0x0000027c
+#define PCR_DZ_TPH_REQ_CTL_REG 0x000001c8
/* hunta0=pci_f0_config */
#define PCRF_DZ_TPH_REQ_ENABLE_LBN 8
@@ -1844,101 +1888,37 @@ extern "C" {
/*
- * PC_SEC_PCIE_CAP_REG(32bit):
- * Secondary PCIE Capability Register
- */
-
-#define PCR_DZ_SEC_PCIE_CAP_REG 0x00000300
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_SEC_NXT_PTR_LBN 20
-#define PCRF_DZ_SEC_NXT_PTR_WIDTH 12
-#define PCRF_DZ_SEC_VERSION_LBN 16
-#define PCRF_DZ_SEC_VERSION_WIDTH 4
-#define PCRF_DZ_SEC_EXT_CAP_ID_LBN 0
-#define PCRF_DZ_SEC_EXT_CAP_ID_WIDTH 16
-
-
-/*
- * PC_LINK_CONTROL3_REG(32bit):
- * Link Control 3.
- */
-
-#define PCR_DZ_LINK_CONTROL3_REG 0x00000304
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LINK_EQ_INT_EN_LBN 1
-#define PCRF_DZ_LINK_EQ_INT_EN_WIDTH 1
-#define PCRF_DZ_PERFORM_EQL_LBN 0
-#define PCRF_DZ_PERFORM_EQL_WIDTH 1
-
-
-/*
- * PC_LANE_ERROR_STAT_REG(32bit):
- * Lane Error Status Register.
- */
-
-#define PCR_DZ_LANE_ERROR_STAT_REG 0x00000308
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LANE_STATUS_LBN 0
-#define PCRF_DZ_LANE_STATUS_WIDTH 8
-
-
-/*
- * PC_LANE01_EQU_CONTROL_REG(32bit):
- * Lanes 0,1 Equalization Control Register.
- */
-
-#define PCR_DZ_LANE01_EQU_CONTROL_REG 0x0000030c
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LANE1_EQ_CTRL_LBN 16
-#define PCRF_DZ_LANE1_EQ_CTRL_WIDTH 16
-#define PCRF_DZ_LANE0_EQ_CTRL_LBN 0
-#define PCRF_DZ_LANE0_EQ_CTRL_WIDTH 16
-
-
-/*
- * PC_LANE23_EQU_CONTROL_REG(32bit):
- * Lanes 2,3 Equalization Control Register.
- */
-
-#define PCR_DZ_LANE23_EQU_CONTROL_REG 0x00000310
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LANE3_EQ_CTRL_LBN 16
-#define PCRF_DZ_LANE3_EQ_CTRL_WIDTH 16
-#define PCRF_DZ_LANE2_EQ_CTRL_LBN 0
-#define PCRF_DZ_LANE2_EQ_CTRL_WIDTH 16
-
-
-/*
- * PC_LANE45_EQU_CONTROL_REG(32bit):
- * Lanes 4,5 Equalization Control Register.
+ * PC_LTR_CAP_HDR_REG(32bit):
+ * Latency Tolerance Reporting Cap Header Reg
*/
-#define PCR_DZ_LANE45_EQU_CONTROL_REG 0x00000314
+#define PCR_DZ_LTR_CAP_HDR_REG 0x00000290
/* hunta0=pci_f0_config */
-#define PCRF_DZ_LANE5_EQ_CTRL_LBN 16
-#define PCRF_DZ_LANE5_EQ_CTRL_WIDTH 16
-#define PCRF_DZ_LANE4_EQ_CTRL_LBN 0
-#define PCRF_DZ_LANE4_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LTR_NXT_PTR_LBN 20
+#define PCRF_DZ_LTR_NXT_PTR_WIDTH 12
+#define PCRF_DZ_LTR_VERSION_LBN 16
+#define PCRF_DZ_LTR_VERSION_WIDTH 4
+#define PCRF_DZ_LTR_EXT_CAP_ID_LBN 0
+#define PCRF_DZ_LTR_EXT_CAP_ID_WIDTH 16
/*
- * PC_LANE67_EQU_CONTROL_REG(32bit):
- * Lanes 6,7 Equalization Control Register.
+ * PC_LTR_MAX_SNOOP_REG(32bit):
+ * LTR Maximum Snoop/No Snoop Register
*/
-#define PCR_DZ_LANE67_EQU_CONTROL_REG 0x00000318
+#define PCR_DZ_LTR_MAX_SNOOP_REG 0x00000294
/* hunta0=pci_f0_config */
-#define PCRF_DZ_LANE7_EQ_CTRL_LBN 16
-#define PCRF_DZ_LANE7_EQ_CTRL_WIDTH 16
-#define PCRF_DZ_LANE6_EQ_CTRL_LBN 0
-#define PCRF_DZ_LANE6_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_LBN 26
+#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_WIDTH 3
+#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_LBN 16
+#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_WIDTH 10
+#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_LBN 10
+#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_WIDTH 3
+#define PCRF_DZ_LTR_MAX_SNOOP_LAT_LBN 0
+#define PCRF_DZ_LTR_MAX_SNOOP_LAT_WIDTH 10
/*
@@ -2140,6 +2120,18 @@ extern "C" {
/*
+ * PC_FLT_MSK_REG(32bit):
+ * Filter Mask Register 2
+ */
+
+#define PCR_CC_FLT_MSK_REG 0x00000720
+/* sienaa0=pci_f0_config */
+
+#define PCRF_CC_DEFAULT_FLT_MSK2_LBN 0
+#define PCRF_CC_DEFAULT_FLT_MSK2_WIDTH 32
+
+
+/*
* PC_PHY_STAT_REG(32bit):
* PHY status register
*/
@@ -2161,18 +2153,6 @@ extern "C" {
/*
- * PC_FLT_MSK_REG(32bit):
- * Filter Mask Register 2
- */
-
-#define PCR_CC_FLT_MSK_REG 0x00000720
-/* sienaa0=pci_f0_config */
-
-#define PCRF_CC_DEFAULT_FLT_MSK2_LBN 0
-#define PCRF_CC_DEFAULT_FLT_MSK2_WIDTH 32
-
-
-/*
* PC_PHY_CTL_REG(32bit):
* PHY control register
*/
diff --git a/sys/dev/sfxge/common/efx_rx.c b/sys/dev/sfxge/common/efx_rx.c
index c6e0d70e064e..3501d6ec0785 100644
--- a/sys/dev/sfxge/common/efx_rx.c
+++ b/sys/dev/sfxge/common/efx_rx.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -32,12 +37,174 @@ __FBSDID("$FreeBSD$");
#include "efx_regs.h"
#include "efx_impl.h"
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_rx_init(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_rx_fini(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_RX_HDR_SPLIT
+static __checkReturn int
+falconsiena_rx_hdr_split_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int hdr_buf_size,
+ __in unsigned int pld_buf_size);
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+#if EFSYS_OPT_RX_SCATTER
+static __checkReturn int
+falconsiena_rx_scatter_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int buf_size);
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+#if EFSYS_OPT_RX_SCALE
+static __checkReturn int
+falconsiena_rx_scale_mode_set(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t alg,
+ __in efx_rx_hash_type_t type,
+ __in boolean_t insert);
+
+static __checkReturn int
+falconsiena_rx_scale_key_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n);
+
+static __checkReturn int
+falconsiena_rx_scale_tbl_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n);
+
+#endif /* EFSYS_OPT_RX_SCALE */
+
+static void
+falconsiena_rx_qpost(
+ __in efx_rxq_t *erp,
+ __in_ecount(n) efsys_dma_addr_t *addrp,
+ __in size_t size,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __in unsigned int added);
+
+static void
+falconsiena_rx_qpush(
+ __in efx_rxq_t *erp,
+ __in unsigned int added,
+ __inout unsigned int *pushedp);
+
+static __checkReturn int
+falconsiena_rx_qflush(
+ __in efx_rxq_t *erp);
+
+static void
+falconsiena_rx_qenable(
+ __in efx_rxq_t *erp);
+
+static __checkReturn int
+falconsiena_rx_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in unsigned int label,
+ __in efx_rxq_type_t type,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in efx_evq_t *eep,
+ __in efx_rxq_t *erp);
+
+static void
+falconsiena_rx_qdestroy(
+ __in efx_rxq_t *erp);
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+
+#if EFSYS_OPT_FALCON
+static efx_rx_ops_t __efx_rx_falcon_ops = {
+ falconsiena_rx_init, /* erxo_init */
+ falconsiena_rx_fini, /* erxo_fini */
+#if EFSYS_OPT_RX_HDR_SPLIT
+ falconsiena_rx_hdr_split_enable, /* erxo_hdr_split_enable */
+#endif
+#if EFSYS_OPT_RX_SCATTER
+ falconsiena_rx_scatter_enable, /* erxo_scatter_enable */
+#endif
+#if EFSYS_OPT_RX_SCALE
+ falconsiena_rx_scale_mode_set, /* erxo_scale_mode_set */
+ falconsiena_rx_scale_key_set, /* erxo_scale_key_set */
+ falconsiena_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+#endif
+ falconsiena_rx_qpost, /* erxo_qpost */
+ falconsiena_rx_qpush, /* erxo_qpush */
+ falconsiena_rx_qflush, /* erxo_qflush */
+ falconsiena_rx_qenable, /* erxo_qenable */
+ falconsiena_rx_qcreate, /* erxo_qcreate */
+ falconsiena_rx_qdestroy, /* erxo_qdestroy */
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_rx_ops_t __efx_rx_siena_ops = {
+ falconsiena_rx_init, /* erxo_init */
+ falconsiena_rx_fini, /* erxo_fini */
+#if EFSYS_OPT_RX_HDR_SPLIT
+ falconsiena_rx_hdr_split_enable, /* erxo_hdr_split_enable */
+#endif
+#if EFSYS_OPT_RX_SCATTER
+ falconsiena_rx_scatter_enable, /* erxo_scatter_enable */
+#endif
+#if EFSYS_OPT_RX_SCALE
+ falconsiena_rx_scale_mode_set, /* erxo_scale_mode_set */
+ falconsiena_rx_scale_key_set, /* erxo_scale_key_set */
+ falconsiena_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+#endif
+ falconsiena_rx_qpost, /* erxo_qpost */
+ falconsiena_rx_qpush, /* erxo_qpush */
+ falconsiena_rx_qflush, /* erxo_qflush */
+ falconsiena_rx_qenable, /* erxo_qenable */
+ falconsiena_rx_qcreate, /* erxo_qcreate */
+ falconsiena_rx_qdestroy, /* erxo_qdestroy */
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_rx_ops_t __efx_rx_hunt_ops = {
+ hunt_rx_init, /* erxo_init */
+ hunt_rx_fini, /* erxo_fini */
+#if EFSYS_OPT_RX_HDR_SPLIT
+ hunt_rx_hdr_split_enable, /* erxo_hdr_split_enable */
+#endif
+#if EFSYS_OPT_RX_SCATTER
+ hunt_rx_scatter_enable, /* erxo_scatter_enable */
+#endif
+#if EFSYS_OPT_RX_SCALE
+ hunt_rx_scale_mode_set, /* erxo_scale_mode_set */
+ hunt_rx_scale_key_set, /* erxo_scale_key_set */
+ hunt_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+#endif
+ hunt_rx_qpost, /* erxo_qpost */
+ hunt_rx_qpush, /* erxo_qpush */
+ hunt_rx_qflush, /* erxo_qflush */
+ hunt_rx_qenable, /* erxo_qenable */
+ hunt_rx_qcreate, /* erxo_qcreate */
+ hunt_rx_qdestroy, /* erxo_qdestroy */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+
__checkReturn int
efx_rx_init(
- __in efx_nic_t *enp)
+ __inout efx_nic_t *enp)
{
- efx_oword_t oword;
- unsigned int index;
+ efx_rx_ops_t *erxop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -53,6 +220,471 @@ efx_rx_init(
goto fail2;
}
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ erxop = (efx_rx_ops_t *)&__efx_rx_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ erxop = (efx_rx_ops_t *)&__efx_rx_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ erxop = (efx_rx_ops_t *)&__efx_rx_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail3;
+ }
+
+ if ((rc = erxop->erxo_init(enp)) != 0)
+ goto fail4;
+
+ enp->en_erxop = erxop;
+ enp->en_mod_flags |= EFX_MOD_RX;
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ enp->en_erxop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_RX;
+ return (rc);
+}
+
+ void
+efx_rx_fini(
+ __in efx_nic_t *enp)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+ EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0);
+
+ erxop->erxo_fini(enp);
+
+ enp->en_erxop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_RX;
+}
+
+#if EFSYS_OPT_RX_HDR_SPLIT
+ __checkReturn int
+efx_rx_hdr_split_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int hdr_buf_size,
+ __in unsigned int pld_buf_size)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+ EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_SIENA);
+
+ if ((rc = erxop->erxo_hdr_split_enable(enp, hdr_buf_size,
+ pld_buf_size)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+#if EFSYS_OPT_RX_SCATTER
+ __checkReturn int
+efx_rx_scatter_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int buf_size)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if ((rc = erxop->erxo_scatter_enable(enp, buf_size)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+efx_rx_hash_support_get(
+ __in efx_nic_t *enp,
+ __out efx_rx_hash_support_t *supportp)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if (supportp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Report if resources are available to insert RX hash value */
+ *supportp = enp->en_hash_support;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_rx_scale_support_get(
+ __in efx_nic_t *enp,
+ __out efx_rx_scale_support_t *supportp)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if (supportp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Report if resources are available to support RSS */
+ *supportp = enp->en_rss_support;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_rx_scale_mode_set(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t alg,
+ __in efx_rx_hash_type_t type,
+ __in boolean_t insert)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if (erxop->erxo_scale_mode_set != NULL) {
+ if ((rc = erxop->erxo_scale_mode_set(enp, alg,
+ type, insert)) != 0)
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+efx_rx_scale_key_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if ((rc = erxop->erxo_scale_key_set(enp, key, n)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+efx_rx_scale_tbl_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if ((rc = erxop->erxo_scale_tbl_set(enp, table, n)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+ void
+efx_rx_qpost(
+ __in efx_rxq_t *erp,
+ __in_ecount(n) efsys_dma_addr_t *addrp,
+ __in size_t size,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __in unsigned int added)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ erxop->erxo_qpost(erp, addrp, size, n, completed, added);
+}
+
+ void
+efx_rx_qpush(
+ __in efx_rxq_t *erp,
+ __in unsigned int added,
+ __inout unsigned int *pushedp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ erxop->erxo_qpush(erp, added, pushedp);
+}
+
+ __checkReturn int
+efx_rx_qflush(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ if ((rc = erxop->erxo_qflush(erp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_rx_qenable(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ erxop->erxo_qenable(erp);
+}
+
+ __checkReturn int
+efx_rx_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in unsigned int label,
+ __in efx_rxq_type_t type,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in efx_evq_t *eep,
+ __deref_out efx_rxq_t **erpp)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ efx_rxq_t *erp;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ /* Allocate an RXQ object */
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
+
+ if (erp == NULL) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+
+ erp->er_magic = EFX_RXQ_MAGIC;
+ erp->er_enp = enp;
+ erp->er_index = index;
+ erp->er_mask = n - 1;
+ erp->er_esmp = esmp;
+
+ if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, n, id,
+ eep, erp)) != 0)
+ goto fail2;
+
+ enp->en_rx_qcount++;
+ *erpp = erp;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_rx_qdestroy(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ erxop->erxo_qdestroy(erp);
+}
+
+/*
+ * Psuedo-header info for Siena/Falcon.
+ *
+ * The psuedo-header is a byte array of one of the forms:
+ *
+ * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.TT.TT.TT.TT
+ * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.LL.LL
+ *
+ * where:
+ *
+ * TT.TT.TT.TT is a 32-bit Toeplitz hash
+ * LL.LL is a 16-bit LFSR hash
+ *
+ * Hash values are in network (big-endian) byte order.
+ *
+ *
+ * On Huntington the pseudo-header is laid out as:
+ * (See also SF-109306-TC section 9)
+ *
+ * Toeplitz hash (32 bits, little-endian)
+ * Out-of-band outer VLAN tag
+ * (16 bits, big-endian, 0 if the packet did not have an outer VLAN tag)
+ * Out-of-band inner VLAN tag
+ * (16 bits, big-endian, 0 if the packet did not have an inner VLAN tag)
+ * Packet length (16 bits, little-endian, may be 0)
+ * MAC timestamp (32 bits, little-endian, may be 0)
+ * VLAN tag
+ * (16 bits, big-endian, 0 if the packet did not have an outer VLAN tag)
+ * VLAN tag
+ * (16 bits, big-endian, 0 if the packet did not have an inner VLAN tag)
+ */
+
+ __checkReturn int
+efx_psuedo_hdr_pkt_length_get(
+ __in efx_nic_t *enp,
+ __in uint8_t *buffer,
+ __out uint16_t *pkt_lengthp)
+{
+ if (enp->en_family != EFX_FAMILY_HUNTINGTON) {
+ EFSYS_ASSERT(0);
+ return (ENOTSUP);
+ }
+
+ *pkt_lengthp = buffer[8] | (buffer[9] << 8);
+
+ return (0);
+}
+
+#if EFSYS_OPT_RX_SCALE
+
+uint32_t
+efx_psuedo_hdr_hash_get(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t func,
+ __in uint8_t *buffer)
+{
+ if (func == EFX_RX_HASHALG_TOEPLITZ) {
+ switch (enp->en_family) {
+ case EFX_FAMILY_FALCON:
+ case EFX_FAMILY_SIENA:
+ return ((buffer[12] << 24) |
+ (buffer[13] << 16) |
+ (buffer[14] << 8) |
+ buffer[15]);
+ case EFX_FAMILY_HUNTINGTON:
+ return (buffer[0] |
+ (buffer[1] << 8) |
+ (buffer[2] << 16) |
+ (buffer[3] << 24));
+ default:
+ EFSYS_ASSERT(0);
+ return (0);
+ }
+ } else if (func == EFX_RX_HASHALG_LFSR) {
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_FALCON ||
+ enp->en_family == EFX_FAMILY_SIENA);
+ return ((buffer[14] << 8) | buffer[15]);
+ } else {
+ EFSYS_ASSERT(0);
+ return (0);
+ }
+}
+
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_rx_init(
+ __in efx_nic_t *enp)
+{
+ efx_oword_t oword;
+ unsigned int index;
+
EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);
@@ -68,23 +700,23 @@ efx_rx_init(
index++) {
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
- index, &oword);
+ index, &oword, B_TRUE);
}
- enp->en_mod_flags |= EFX_MOD_RX;
- return (0);
+#if EFSYS_OPT_RX_SCALE
+ /* The RSS key and indirection table are writable. */
+ enp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ /* Hardware can insert RX hash with/without RSS */
+ enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
+#endif /* EFSYS_OPT_RX_SCALE */
- return (rc);
+ return (0);
}
#if EFSYS_OPT_RX_HDR_SPLIT
- __checkReturn int
-efx_rx_hdr_split_enable(
+static __checkReturn int
+falconsiena_rx_hdr_split_enable(
__in efx_nic_t *enp,
__in unsigned int hdr_buf_size,
__in unsigned int pld_buf_size)
@@ -94,10 +726,6 @@ efx_rx_hdr_split_enable(
efx_oword_t oword;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
- EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_SIENA);
-
nhdr32 = hdr_buf_size / 32;
if ((nhdr32 == 0) ||
(nhdr32 >= (1 << FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_WIDTH)) ||
@@ -140,10 +768,9 @@ fail1:
}
#endif /* EFSYS_OPT_RX_HDR_SPLIT */
-
#if EFSYS_OPT_RX_SCATTER
- __checkReturn int
-efx_rx_scatter_enable(
+static __checkReturn int
+falconsiena_rx_scatter_enable(
__in efx_nic_t *enp,
__in unsigned int buf_size)
{
@@ -151,10 +778,6 @@ efx_rx_scatter_enable(
efx_oword_t oword;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
- EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_FALCON);
-
nbuf32 = buf_size / 32;
if ((nbuf32 == 0) ||
(nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) ||
@@ -191,7 +814,7 @@ fail1:
#define EFX_RX_LFSR_HASH(_enp, _insert) \
- do { \
+ do { \
efx_oword_t oword; \
\
EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \
@@ -215,7 +838,7 @@ fail1:
} while (B_FALSE)
#define EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp) \
- do { \
+ do { \
efx_oword_t oword; \
\
EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \
@@ -232,7 +855,7 @@ fail1:
} while (B_FALSE)
#define EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc) \
- do { \
+ do { \
efx_oword_t oword; \
\
if ((_enp)->en_family == EFX_FAMILY_FALCON) { \
@@ -256,8 +879,9 @@ fail1:
#if EFSYS_OPT_RX_SCALE
- __checkReturn int
-efx_rx_scale_mode_set(
+
+static __checkReturn int
+falconsiena_rx_scale_mode_set(
__in efx_nic_t *enp,
__in efx_rx_hash_alg_t alg,
__in efx_rx_hash_type_t type,
@@ -265,10 +889,6 @@ efx_rx_scale_mode_set(
{
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
- EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_FALCON);
-
switch (alg) {
case EFX_RX_HASHALG_LFSR:
EFX_RX_LFSR_HASH(enp, insert);
@@ -307,8 +927,8 @@ fail1:
#endif
#if EFSYS_OPT_RX_SCALE
- __checkReturn int
-efx_rx_scale_toeplitz_ipv4_key_set(
+static __checkReturn int
+falconsiena_rx_scale_key_set(
__in efx_nic_t *enp,
__in_ecount(n) uint8_t *key,
__in size_t n)
@@ -318,12 +938,9 @@ efx_rx_scale_toeplitz_ipv4_key_set(
unsigned int offset;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
-
byte = 0;
- /* Write toeplitz hash key */
+ /* Write Toeplitz IPv4 hash key */
EFX_ZERO_OWORD(oword);
for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
offset > 0 && byte < n;
@@ -334,7 +951,7 @@ efx_rx_scale_toeplitz_ipv4_key_set(
byte = 0;
- /* Verify toeplitz hash key */
+ /* Verify Toeplitz IPv4 hash key */
EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
offset > 0 && byte < n;
@@ -345,33 +962,14 @@ efx_rx_scale_toeplitz_ipv4_key_set(
}
}
- return (0);
+ if ((enp->en_features & EFX_FEATURE_IPV6) == 0)
+ goto done;
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-#endif
-
-#if EFSYS_OPT_RX_SCALE
- __checkReturn int
-efx_rx_scale_toeplitz_ipv6_key_set(
- __in efx_nic_t *enp,
- __in_ecount(n) uint8_t *key,
- __in size_t n)
-{
- efx_oword_t oword;
- unsigned int byte;
- int offset;
- int rc;
-
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+ EFSYS_ASSERT3U(enp->en_family, !=, EFX_FAMILY_FALCON);
byte = 0;
- /* Write toeplitz hash key 3 */
+ /* Write Toeplitz IPv6 hash key 3 */
EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
@@ -381,7 +979,7 @@ efx_rx_scale_toeplitz_ipv6_key_set(
EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
- /* Write toeplitz hash key 2 */
+ /* Write Toeplitz IPv6 hash key 2 */
EFX_ZERO_OWORD(oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
@@ -391,7 +989,7 @@ efx_rx_scale_toeplitz_ipv6_key_set(
EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
- /* Write toeplitz hash key 1 */
+ /* Write Toeplitz IPv6 hash key 1 */
EFX_ZERO_OWORD(oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
@@ -403,7 +1001,7 @@ efx_rx_scale_toeplitz_ipv6_key_set(
byte = 0;
- /* Verify toeplitz hash key 3 */
+ /* Verify Toeplitz IPv6 hash key 3 */
EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
@@ -411,11 +1009,11 @@ efx_rx_scale_toeplitz_ipv6_key_set(
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail1;
+ goto fail2;
}
}
- /* Verify toeplitz hash key 2 */
+ /* Verify Toeplitz IPv6 hash key 2 */
EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
@@ -423,11 +1021,11 @@ efx_rx_scale_toeplitz_ipv6_key_set(
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail2;
+ goto fail3;
}
}
- /* Verify toeplitz hash key 1 */
+ /* Verify Toeplitz IPv6 hash key 1 */
EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
@@ -435,12 +1033,15 @@ efx_rx_scale_toeplitz_ipv6_key_set(
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail3;
+ goto fail4;
}
}
+done:
return (0);
+fail4:
+ EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
fail2:
@@ -453,8 +1054,8 @@ fail1:
#endif
#if EFSYS_OPT_RX_SCALE
- __checkReturn int
-efx_rx_scale_tbl_set(
+static __checkReturn int
+falconsiena_rx_scale_tbl_set(
__in efx_nic_t *enp,
__in_ecount(n) unsigned int *table,
__in size_t n)
@@ -463,9 +1064,6 @@ efx_rx_scale_tbl_set(
int index;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
-
EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);
EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));
@@ -478,7 +1076,7 @@ efx_rx_scale_tbl_set(
uint32_t byte;
/* Calculate the entry to place in the table */
- byte = (uint32_t)table[index % n];
+ byte = (n > 0) ? (uint32_t)table[index % n] : 0;
EFSYS_PROBE2(table, int, index, uint32_t, byte);
@@ -486,18 +1084,18 @@ efx_rx_scale_tbl_set(
/* Write the table */
EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
- index, &oword);
+ index, &oword, B_TRUE);
}
for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {
uint32_t byte;
/* Determine if we're starting a new batch */
- byte = (uint32_t)table[index % n];
+ byte = (n > 0) ? (uint32_t)table[index % n] : 0;
/* Read the table */
EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,
- index, &oword);
+ index, &oword, B_TRUE);
/* Verify the entry */
if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {
@@ -517,36 +1115,8 @@ fail1:
}
#endif
-#if EFSYS_OPT_FILTER
-extern __checkReturn int
-efx_rx_filter_insert(
- __in efx_rxq_t *erp,
- __inout efx_filter_spec_t *spec)
-{
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
- EFSYS_ASSERT3P(spec, !=, NULL);
-
- spec->efs_dmaq_id = (uint16_t)erp->er_index;
- return (efx_filter_insert_filter(erp->er_enp, spec, B_FALSE));
-}
-#endif
-
-#if EFSYS_OPT_FILTER
-extern __checkReturn int
-efx_rx_filter_remove(
- __in efx_rxq_t *erp,
- __inout efx_filter_spec_t *spec)
-{
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
- EFSYS_ASSERT3P(spec, !=, NULL);
-
- spec->efs_dmaq_id = (uint16_t)erp->er_index;
- return (efx_filter_remove_filter(erp->er_enp, spec));
-}
-#endif
-
-extern void
-efx_rx_qpost(
+static void
+falconsiena_rx_qpost(
__in efx_rxq_t *erp,
__in_ecount(n) efsys_dma_addr_t *addrp,
__in size_t size,
@@ -559,8 +1129,6 @@ efx_rx_qpost(
unsigned int offset;
unsigned int id;
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
-
/* The client driver must not overfill the queue */
EFSYS_ASSERT3U(added - completed + n, <=,
EFX_RXQ_LIMIT(erp->er_mask + 1));
@@ -585,20 +1153,20 @@ efx_rx_qpost(
}
}
- void
-efx_rx_qpush(
+static void
+falconsiena_rx_qpush(
__in efx_rxq_t *erp,
- __in unsigned int added)
+ __in unsigned int added,
+ __inout unsigned int *pushedp)
{
efx_nic_t *enp = erp->er_enp;
+ unsigned int pushed = *pushedp;
uint32_t wptr;
efx_oword_t oword;
efx_dword_t dword;
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
-
- /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
- EFSYS_PIO_WRITE_BARRIER();
+ /* All descriptors are pushed */
+ *pushedp = added;
/* Push the populated descriptors out */
wptr = added & erp->er_mask;
@@ -608,30 +1176,35 @@ efx_rx_qpush(
/* Only write the third DWORD */
EFX_POPULATE_DWORD_1(dword,
EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
+
+ /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
+ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
+ wptr, pushed & erp->er_mask);
+ EFSYS_PIO_WRITE_BARRIER();
EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,
erp->er_index, &dword, B_FALSE);
}
- void
-efx_rx_qflush(
+static __checkReturn int
+falconsiena_rx_qflush(
__in efx_rxq_t *erp)
{
efx_nic_t *enp = erp->er_enp;
efx_oword_t oword;
uint32_t label;
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
-
label = erp->er_index;
/* Flush the queue */
EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
FRF_AZ_RX_FLUSH_DESCQ, label);
EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);
+
+ return (0);
}
- void
-efx_rx_qenable(
+static void
+falconsiena_rx_qenable(
__in efx_rxq_t *erp)
{
efx_nic_t *enp = erp->er_enp;
@@ -640,18 +1213,18 @@ efx_rx_qenable(
EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,
- erp->er_index, &oword);
+ erp->er_index, &oword, B_TRUE);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
- erp->er_index, &oword);
+ erp->er_index, &oword, B_TRUE);
}
- __checkReturn int
-efx_rx_qcreate(
+static __checkReturn int
+falconsiena_rx_qcreate(
__in efx_nic_t *enp,
__in unsigned int index,
__in unsigned int label,
@@ -660,25 +1233,24 @@ efx_rx_qcreate(
__in size_t n,
__in uint32_t id,
__in efx_evq_t *eep,
- __deref_out efx_rxq_t **erpp)
+ __in efx_rxq_t *erp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_rxq_t *erp;
efx_oword_t oword;
uint32_t size;
boolean_t split;
boolean_t jumbo;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
-
EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
(1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
- if (!ISP2(n) || !(n & EFX_RXQ_NDESCS_MASK)) {
+ EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
+ EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
+
+ if (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) {
rc = EINVAL;
goto fail1;
}
@@ -737,20 +1309,6 @@ efx_rx_qcreate(
goto fail4;
}
- /* Allocate an RXQ object */
- EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
-
- if (erp == NULL) {
- rc = ENOMEM;
- goto fail5;
- }
-
- erp->er_magic = EFX_RXQ_MAGIC;
- erp->er_enp = enp;
- erp->er_index = index;
- erp->er_mask = n - 1;
- erp->er_esmp = esmp;
-
/* Set up the new descriptor queue */
EFX_POPULATE_OWORD_10(oword,
FRF_CZ_RX_HDR_SPLIT, split,
@@ -765,14 +1323,10 @@ efx_rx_qcreate(
FRF_AZ_RX_DESCQ_JUMBO, jumbo);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
- erp->er_index, &oword);
+ erp->er_index, &oword, B_TRUE);
- enp->en_rx_qcount++;
- *erpp = erp;
return (0);
-fail5:
- EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
fail3:
@@ -785,15 +1339,13 @@ fail1:
return (rc);
}
- void
-efx_rx_qdestroy(
+static void
+falconsiena_rx_qdestroy(
__in efx_rxq_t *erp)
{
efx_nic_t *enp = erp->er_enp;
efx_oword_t oword;
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
-
EFSYS_ASSERT(enp->en_rx_qcount != 0);
--enp->en_rx_qcount;
@@ -801,20 +1353,17 @@ efx_rx_qdestroy(
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
- erp->er_index, &oword);
+ erp->er_index, &oword, B_TRUE);
/* Free the RXQ object */
EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
}
- void
-efx_rx_fini(
+static void
+falconsiena_rx_fini(
__in efx_nic_t *enp)
{
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
- EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0);
-
- enp->en_mod_flags &= ~EFX_MOD_RX;
+ _NOTE(ARGUNUSED(enp))
}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_sram.c b/sys/dev/sfxge/common/efx_sram.c
index f081adf391e5..4bd951b7466b 100644
--- a/sys/dev/sfxge/common/efx_sram.c
+++ b/sys/dev/sfxge/common/efx_sram.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -50,6 +55,21 @@ efx_sram_buf_tbl_set(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /*
+ * FIXME: the efx_sram_buf_tbl_*() functionality needs to be
+ * pulled inside the Falcon/Siena queue create/destroy code,
+ * and then the original functions can be removed (see bug30834
+ * comment #1). But, for now, we just ensure that they are
+ * no-ops for Huntington, to allow bringing up existing drivers
+ * without modification.
+ */
+
+ return (0);
+ }
+#endif /* EFSYS_OPT_HUNTINGTON */
+
if (stop >= EFX_BUF_TBL_SIZE) {
rc = EFBIG;
goto fail1;
@@ -156,6 +176,21 @@ efx_sram_buf_tbl_clear(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /*
+ * FIXME: the efx_sram_buf_tbl_*() functionality needs to be
+ * pulled inside the Falcon/Siena queue create/destroy code,
+ * and then the original functions can be removed (see bug30834
+ * comment #1). But, for now, we just ensure that they are
+ * no-ops for Huntington, to allow bringing up existing drivers
+ * without modification.
+ */
+
+ return;
+ }
+#endif /* EFSYS_OPT_HUNTINGTON */
+
EFSYS_ASSERT3U(stop, <, EFX_BUF_TBL_SIZE);
EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1);
@@ -262,7 +297,7 @@ efx_sram_bit_sweep_set(
}
}
-efx_sram_pattern_fn_t __cs __efx_sram_pattern_fns[] = {
+efx_sram_pattern_fn_t __efx_sram_pattern_fns[] = {
efx_sram_byte_increment_set,
efx_sram_all_the_same_set,
efx_sram_bit_alternate_set,
diff --git a/sys/dev/sfxge/common/efx_tx.c b/sys/dev/sfxge/common/efx_tx.c
index 2b0f5e5fffdd..a2e876923ed5 100644
--- a/sys/dev/sfxge/common/efx_tx.c
+++ b/sys/dev/sfxge/common/efx_tx.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -42,11 +47,166 @@ __FBSDID("$FreeBSD$");
#define EFX_TX_QSTAT_INCR(_etp, _stat)
#endif
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_tx_init(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_tx_fini(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_tx_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in unsigned int label,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in uint16_t flags,
+ __in efx_evq_t *eep,
+ __in efx_txq_t *etp,
+ __out unsigned int *addedp);
+
+static void
+falconsiena_tx_qdestroy(
+ __in efx_txq_t *etp);
+
+static __checkReturn int
+falconsiena_tx_qpost(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_buffer_t *eb,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+static void
+falconsiena_tx_qpush(
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed);
+
+static __checkReturn int
+falconsiena_tx_qpace(
+ __in efx_txq_t *etp,
+ __in unsigned int ns);
+
+static __checkReturn int
+falconsiena_tx_qflush(
+ __in efx_txq_t *etp);
+
+static void
+falconsiena_tx_qenable(
+ __in efx_txq_t *etp);
+
+ __checkReturn int
+falconsiena_tx_qdesc_post(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_desc_t *ed,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+ void
+falconsiena_tx_qdesc_dma_create(
+ __in efx_txq_t *etp,
+ __in efsys_dma_addr_t addr,
+ __in size_t size,
+ __in boolean_t eop,
+ __out efx_desc_t *edp);
+
+#if EFSYS_OPT_QSTATS
+static void
+falconsiena_tx_qstats_update(
+ __in efx_txq_t *etp,
+ __inout_ecount(TX_NQSTATS) efsys_stat_t *stat);
+#endif
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+
+#if EFSYS_OPT_FALCON
+static efx_tx_ops_t __efx_tx_falcon_ops = {
+ falconsiena_tx_init, /* etxo_init */
+ falconsiena_tx_fini, /* etxo_fini */
+ falconsiena_tx_qcreate, /* etxo_qcreate */
+ falconsiena_tx_qdestroy, /* etxo_qdestroy */
+ falconsiena_tx_qpost, /* etxo_qpost */
+ falconsiena_tx_qpush, /* etxo_qpush */
+ falconsiena_tx_qpace, /* etxo_qpace */
+ falconsiena_tx_qflush, /* etxo_qflush */
+ falconsiena_tx_qenable, /* etxo_qenable */
+ NULL, /* etxo_qpio_enable */
+ NULL, /* etxo_qpio_disable */
+ NULL, /* etxo_qpio_write */
+ NULL, /* etxo_qpio_post */
+ falconsiena_tx_qdesc_post, /* etxo_qdesc_post */
+ falconsiena_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
+ NULL, /* etxo_qdesc_tso_create */
+ NULL, /* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+ falconsiena_tx_qstats_update, /* etxo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_tx_ops_t __efx_tx_siena_ops = {
+ falconsiena_tx_init, /* etxo_init */
+ falconsiena_tx_fini, /* etxo_fini */
+ falconsiena_tx_qcreate, /* etxo_qcreate */
+ falconsiena_tx_qdestroy, /* etxo_qdestroy */
+ falconsiena_tx_qpost, /* etxo_qpost */
+ falconsiena_tx_qpush, /* etxo_qpush */
+ falconsiena_tx_qpace, /* etxo_qpace */
+ falconsiena_tx_qflush, /* etxo_qflush */
+ falconsiena_tx_qenable, /* etxo_qenable */
+ NULL, /* etxo_qpio_enable */
+ NULL, /* etxo_qpio_disable */
+ NULL, /* etxo_qpio_write */
+ NULL, /* etxo_qpio_post */
+ falconsiena_tx_qdesc_post, /* etxo_qdesc_post */
+ falconsiena_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
+ NULL, /* etxo_qdesc_tso_create */
+ NULL, /* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+ falconsiena_tx_qstats_update, /* etxo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_tx_ops_t __efx_tx_hunt_ops = {
+ hunt_tx_init, /* etxo_init */
+ hunt_tx_fini, /* etxo_fini */
+ hunt_tx_qcreate, /* etxo_qcreate */
+ hunt_tx_qdestroy, /* etxo_qdestroy */
+ hunt_tx_qpost, /* etxo_qpost */
+ hunt_tx_qpush, /* etxo_qpush */
+ hunt_tx_qpace, /* etxo_qpace */
+ hunt_tx_qflush, /* etxo_qflush */
+ hunt_tx_qenable, /* etxo_qenable */
+ hunt_tx_qpio_enable, /* etxo_qpio_enable */
+ hunt_tx_qpio_disable, /* etxo_qpio_disable */
+ hunt_tx_qpio_write, /* etxo_qpio_write */
+ hunt_tx_qpio_post, /* etxo_qpio_post */
+ hunt_tx_qdesc_post, /* etxo_qdesc_post */
+ hunt_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
+ hunt_tx_qdesc_tso_create, /* etxo_qdesc_tso_create */
+ hunt_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+ hunt_tx_qstats_update, /* etxo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_tx_init(
__in efx_nic_t *enp)
{
- efx_oword_t oword;
+ efx_tx_ops_t *etxop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -62,8 +222,436 @@ efx_tx_init(
goto fail2;
}
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ etxop = (efx_tx_ops_t *)&__efx_tx_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ etxop = (efx_tx_ops_t *)&__efx_tx_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ etxop = (efx_tx_ops_t *)&__efx_tx_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail3;
+ }
+
EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
+ if ((rc = etxop->etxo_init(enp)) != 0)
+ goto fail4;
+
+ enp->en_etxop = etxop;
+ enp->en_mod_flags |= EFX_MOD_TX;
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ enp->en_etxop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_TX;
+ return (rc);
+}
+
+ void
+efx_tx_fini(
+ __in efx_nic_t *enp)
+{
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
+ EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
+
+ etxop->etxo_fini(enp);
+
+ enp->en_etxop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_TX;
+}
+
+ __checkReturn int
+efx_tx_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in unsigned int label,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in uint16_t flags,
+ __in efx_evq_t *eep,
+ __deref_out efx_txq_t **etpp,
+ __out unsigned int *addedp)
+{
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_txq_t *etp;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
+
+ EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit);
+
+ /* Allocate an TXQ object */
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
+
+ if (etp == NULL) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+
+ etp->et_magic = EFX_TXQ_MAGIC;
+ etp->et_enp = enp;
+ etp->et_index = index;
+ etp->et_mask = n - 1;
+ etp->et_esmp = esmp;
+
+ /* Initial descriptor index may be modified by etxo_qcreate */
+ *addedp = 0;
+
+ if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
+ n, id, flags, eep, etp, addedp)) != 0)
+ goto fail2;
+
+ enp->en_tx_qcount++;
+ *etpp = etp;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+efx_tx_qdestroy(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ EFSYS_ASSERT(enp->en_tx_qcount != 0);
+ --enp->en_tx_qcount;
+
+ etxop->etxo_qdestroy(etp);
+
+ /* Free the TXQ object */
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
+}
+
+ __checkReturn int
+efx_tx_qpost(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_buffer_t *eb,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int rc;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if ((rc = etxop->etxo_qpost(etp, eb,
+ n, completed, addedp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+efx_tx_qpush(
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ etxop->etxo_qpush(etp, added, pushed);
+}
+
+ __checkReturn int
+efx_tx_qpace(
+ __in efx_txq_t *etp,
+ __in unsigned int ns)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int rc;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ __checkReturn int
+efx_tx_qflush(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int rc;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if ((rc = etxop->etxo_qflush(etp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+efx_tx_qenable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ etxop->etxo_qenable(etp);
+}
+
+ __checkReturn int
+efx_tx_qpio_enable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int rc;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ if (etxop->etxo_qpio_enable == NULL) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+ if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+efx_tx_qpio_disable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if (etxop->etxo_qpio_disable != NULL)
+ etxop->etxo_qpio_disable(etp);
+}
+
+ __checkReturn int
+efx_tx_qpio_write(
+ __in efx_txq_t *etp,
+ __in_ecount(buf_length) uint8_t *buffer,
+ __in size_t buf_length,
+ __in size_t pio_buf_offset)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int rc;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if (etxop->etxo_qpio_write != NULL) {
+ if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
+ pio_buf_offset)) != 0)
+ goto fail1;
+ return (0);
+ }
+
+ return (ENOTSUP);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ __checkReturn int
+efx_tx_qpio_post(
+ __in efx_txq_t *etp,
+ __in size_t pkt_length,
+ __in unsigned int completed,
+ __inout unsigned int *addedp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int rc;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if (etxop->etxo_qpio_post != NULL) {
+ if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
+ addedp)) != 0)
+ goto fail1;
+ return (0);
+ }
+
+ return (ENOTSUP);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ __checkReturn int
+efx_tx_qdesc_post(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_desc_t *ed,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int rc;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if ((rc = etxop->etxo_qdesc_post(etp, ed,
+ n, completed, addedp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+efx_tx_qdesc_dma_create(
+ __in efx_txq_t *etp,
+ __in efsys_dma_addr_t addr,
+ __in size_t size,
+ __in boolean_t eop,
+ __out efx_desc_t *edp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+ EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
+
+ etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
+}
+
+ void
+efx_tx_qdesc_tso_create(
+ __in efx_txq_t *etp,
+ __in uint16_t ipv4_id,
+ __in uint32_t tcp_seq,
+ __in uint8_t tcp_flags,
+ __out efx_desc_t *edp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+ EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
+
+ etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
+}
+
+ void
+efx_tx_qdesc_vlantci_create(
+ __in efx_txq_t *etp,
+ __in uint16_t tci,
+ __out efx_desc_t *edp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+ EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
+
+ etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
+}
+
+
+#if EFSYS_OPT_QSTATS
+ void
+efx_tx_qstats_update(
+ __in efx_txq_t *etp,
+ __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ etxop->etxo_qstats_update(etp, stat);
+}
+#endif
+
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_tx_init(
+ __in efx_nic_t *enp)
+{
+ efx_oword_t oword;
+
/*
* Disable the timer-based TX DMA backoff and allow TX DMA to be
* controlled by the RX FIFO fill level (although always allow a
@@ -93,44 +681,8 @@ efx_tx_init(
EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
- enp->en_mod_flags |= EFX_MOD_TX;
return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-#if EFSYS_OPT_FILTER
-extern __checkReturn int
-efx_tx_filter_insert(
- __in efx_txq_t *etp,
- __inout efx_filter_spec_t *spec)
-{
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
- EFSYS_ASSERT3P(spec, !=, NULL);
-
- spec->efs_dmaq_id = (uint16_t)etp->et_index;
- return (efx_filter_insert_filter(etp->et_enp, spec, B_FALSE));
-}
-#endif
-
-#if EFSYS_OPT_FILTER
-extern __checkReturn int
-efx_tx_filter_remove(
- __in efx_txq_t *etp,
- __inout efx_filter_spec_t *spec)
-{
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
- EFSYS_ASSERT3P(spec, !=, NULL);
-
- spec->efs_dmaq_id = (uint16_t)etp->et_index;
- return (efx_filter_remove_filter(etp->et_enp, spec));
}
-#endif
#define EFX_TX_DESC(_etp, _addr, _size, _eop, _added) \
do { \
@@ -157,8 +709,8 @@ efx_tx_filter_remove(
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
- __checkReturn int
-efx_tx_qpost(
+static __checkReturn int
+falconsiena_tx_qpost(
__in efx_txq_t *etp,
__in_ecount(n) efx_buffer_t *eb,
__in unsigned int n,
@@ -169,8 +721,6 @@ efx_tx_qpost(
unsigned int i;
int rc = ENOSPC;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1))
goto fail1;
@@ -197,21 +747,17 @@ fail1:
return (rc);
}
- void
-efx_tx_qpush(
+static void
+falconsiena_tx_qpush(
__in efx_txq_t *etp,
- __in unsigned int added)
+ __in unsigned int added,
+ __in unsigned int pushed)
{
efx_nic_t *enp = etp->et_enp;
uint32_t wptr;
efx_dword_t dword;
efx_oword_t oword;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
- /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
- EFSYS_PIO_WRITE_BARRIER();
-
/* Push the populated descriptors out */
wptr = added & etp->et_mask;
@@ -220,6 +766,11 @@ efx_tx_qpush(
/* Only write the third DWORD */
EFX_POPULATE_DWORD_1(dword,
EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
+
+ /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
+ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
+ wptr, pushed & etp->et_mask);
+ EFSYS_PIO_WRITE_BARRIER();
EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,
etp->et_index, &dword, B_FALSE);
}
@@ -227,8 +778,8 @@ efx_tx_qpush(
#define EFX_MAX_PACE_VALUE 20
#define EFX_TX_PACE_CLOCK_BASE 104
- __checkReturn int
-efx_tx_qpace(
+static __checkReturn int
+falconsiena_tx_qpace(
__in efx_txq_t *etp,
__in unsigned int ns)
{
@@ -239,8 +790,6 @@ efx_tx_qpace(
unsigned int timer_period;
int rc;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
if (ns == 0) {
pace_val = 0;
} else {
@@ -261,7 +810,8 @@ efx_tx_qpace(
/* Update the pacing table */
EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,
+ &oword, B_TRUE);
return (0);
@@ -271,16 +821,14 @@ fail1:
return (rc);
}
- void
-efx_tx_qflush(
- __in efx_txq_t *etp)
+static __checkReturn int
+falconsiena_tx_qflush(
+ __in efx_txq_t *etp)
{
efx_nic_t *enp = etp->et_enp;
efx_oword_t oword;
uint32_t label;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
efx_tx_qpace(etp, 0);
label = etp->et_index;
@@ -289,19 +837,19 @@ efx_tx_qflush(
EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
FRF_AZ_TX_FLUSH_DESCQ, label);
EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);
+
+ return (0);
}
- void
-efx_tx_qenable(
+static void
+falconsiena_tx_qenable(
__in efx_txq_t *etp)
{
efx_nic_t *enp = etp->et_enp;
efx_oword_t oword;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
- etp->et_index, &oword);
+ etp->et_index, &oword, B_TRUE);
EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,
uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),
@@ -314,11 +862,11 @@ efx_tx_qenable(
EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
- etp->et_index, &oword);
+ etp->et_index, &oword, B_TRUE);
}
- __checkReturn int
-efx_tx_qcreate(
+static __checkReturn int
+falconsiena_tx_qcreate(
__in efx_nic_t *enp,
__in unsigned int index,
__in unsigned int label,
@@ -327,23 +875,22 @@ efx_tx_qcreate(
__in uint32_t id,
__in uint16_t flags,
__in efx_evq_t *eep,
- __deref_out efx_txq_t **etpp)
+ __in efx_txq_t *etp,
+ __out unsigned int *addedp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_txq_t *etp;
efx_oword_t oword;
uint32_t size;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
-
EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
(1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
- EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit);
- if (!ISP2(n) || !(n & EFX_TXQ_NDESCS_MASK)) {
+ EFSYS_ASSERT(ISP2(EFX_TXQ_MAXNDESCS(encp)));
+ EFX_STATIC_ASSERT(ISP2(EFX_TXQ_MINNDESCS));
+
+ if (!ISP2(n) || (n < EFX_TXQ_MINNDESCS) || (n > EFX_EVQ_MAXNEVS)) {
rc = EINVAL;
goto fail1;
}
@@ -351,7 +898,8 @@ efx_tx_qcreate(
rc = EINVAL;
goto fail2;
}
- for (size = 0; (1 << size) <= (EFX_TXQ_MAXNDESCS / EFX_TXQ_MINNDESCS);
+ for (size = 0;
+ (1 << size) <= (EFX_TXQ_MAXNDESCS(encp) / EFX_TXQ_MINNDESCS);
size++)
if ((1 << size) == (int)(n / EFX_TXQ_MINNDESCS))
break;
@@ -360,20 +908,6 @@ efx_tx_qcreate(
goto fail3;
}
- /* Allocate an TXQ object */
- EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
-
- if (etp == NULL) {
- rc = ENOMEM;
- goto fail4;
- }
-
- etp->et_magic = EFX_TXQ_MAGIC;
- etp->et_enp = enp;
- etp->et_index = index;
- etp->et_mask = n - 1;
- etp->et_esmp = esmp;
-
/* Set up the new descriptor queue */
EFX_POPULATE_OWORD_6(oword,
FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,
@@ -390,14 +924,10 @@ efx_tx_qcreate(
(flags & EFX_CKSUM_TCPUDP) ? 0 : 1);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
- etp->et_index, &oword);
+ etp->et_index, &oword, B_TRUE);
- enp->en_tx_qcount++;
- *etpp = etp;
return (0);
-fail4:
- EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
fail2:
@@ -408,16 +938,83 @@ fail1:
return (rc);
}
+ __checkReturn int
+falconsiena_tx_qdesc_post(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_desc_t *ed,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp)
+{
+ unsigned int added = *addedp;
+ unsigned int i;
+ int rc;
+
+ if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ for (i = 0; i < n; i++) {
+ efx_desc_t *edp = &ed[i];
+ unsigned int id;
+ size_t offset;
+
+ id = added++ & etp->et_mask;
+ offset = id * sizeof (efx_desc_t);
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
+ }
+
+ EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
+ unsigned int, added, unsigned int, n);
+
+ EFX_TX_QSTAT_INCR(etp, TX_POST);
+
+ *addedp = added;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+falconsiena_tx_qdesc_dma_create(
+ __in efx_txq_t *etp,
+ __in efsys_dma_addr_t addr,
+ __in size_t size,
+ __in boolean_t eop,
+ __out efx_desc_t *edp)
+{
+ /* Fragments must not span 4k boundaries. */
+ EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
+
+ EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
+ efsys_dma_addr_t, addr,
+ size_t, size, boolean_t, eop);
+
+ EFX_POPULATE_QWORD_4(edp->ed_eq,
+ FSF_AZ_TX_KER_CONT, eop ? 0 : 1,
+ FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,
+ FSF_AZ_TX_KER_BUF_ADDR_DW0,
+ (uint32_t)(addr & 0xffffffff),
+ FSF_AZ_TX_KER_BUF_ADDR_DW1,
+ (uint32_t)(addr >> 32));
+}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
#if EFSYS_OPT_QSTATS
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 78ca9ab00287fffb */
-static const char __cs * __cs __efx_tx_qstat_name[] = {
+/* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 9d8d26a0a5e2c453 */
+static const char *__efx_tx_qstat_name[] = {
"post",
- "unaligned_split",
+ "post_pio",
};
/* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */
- const char __cs *
+ const char *
efx_tx_qstat_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -429,18 +1026,18 @@ efx_tx_qstat_name(
return (__efx_tx_qstat_name[id]);
}
#endif /* EFSYS_OPT_NAMES */
-#endif /* EFSYS_OPT_QSTATS */
+#endif /* EFSYS_OPT_QSTATS */
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
#if EFSYS_OPT_QSTATS
- void
-efx_tx_qstats_update(
+static void
+falconsiena_tx_qstats_update(
__in efx_txq_t *etp,
__inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
{
unsigned int id;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
for (id = 0; id < TX_NQSTATS; id++) {
efsys_stat_t *essp = &stat[id];
@@ -450,36 +1047,25 @@ efx_tx_qstats_update(
}
#endif /* EFSYS_OPT_QSTATS */
- void
-efx_tx_qdestroy(
+static void
+falconsiena_tx_qdestroy(
__in efx_txq_t *etp)
{
efx_nic_t *enp = etp->et_enp;
efx_oword_t oword;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
- EFSYS_ASSERT(enp->en_tx_qcount != 0);
- --enp->en_tx_qcount;
-
/* Purge descriptor queue */
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
- etp->et_index, &oword);
-
- /* Free the TXQ object */
- EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
+ etp->et_index, &oword, B_TRUE);
}
- void
-efx_tx_fini(
+static void
+falconsiena_tx_fini(
__in efx_nic_t *enp)
{
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
- EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
-
- enp->en_mod_flags &= ~EFX_MOD_TX;
+ _NOTE(ARGUNUSED(enp))
}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_types.h b/sys/dev/sfxge/common/efx_types.h
index 9fbaea11a76b..ee357b1c0dc6 100644
--- a/sys/dev/sfxge/common/efx_types.h
+++ b/sys/dev/sfxge/common/efx_types.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* Ackowledgement to Fen Systems Ltd.
*
@@ -113,11 +118,10 @@ extern "C" {
#define EFX_DWORD_3_LBN 96
#define EFX_DWORD_3_WIDTH 32
-#define EFX_QWORD_0_LBN 0
-#define EFX_QWORD_0_WIDTH 64
-
-#define EFX_QWORD_1_LBN 64
-#define EFX_QWORD_1_WIDTH 64
+/* There are intentionally no EFX_QWORD_0 or EFX_QWORD_1 field definitions
+ * here as the implementaion of EFX_QWORD_FIELD and EFX_OWORD_FIELD do not
+ * support field widths larger than 32 bits.
+ */
/* Specified attribute (i.e. LBN ow WIDTH) of the specified field */
#define EFX_VAL(_field, _attribute) \
@@ -229,6 +233,9 @@ typedef union efx_oword_u {
efx_word_t eo_word[8];
efx_dword_t eo_dword[4];
efx_qword_t eo_qword[2];
+#if EFSYS_HAS_SSE2_M128
+ __m128i eo_u128[1];
+#endif
#if EFSYS_HAS_UINT64
uint64_t eo_u64[2];
#endif
@@ -891,11 +898,7 @@ extern int fix_lint;
#define EFX_ZERO_OWORD(_oword) \
EFX_POPULATE_OWORD_1(_oword, EFX_DUMMY_FIELD, 0)
-#define EFX_SET_OWORD64(_oword) \
- EFX_POPULATE_OWORD_2(_oword, \
- EFX_QWORD_0, (uint64_t)-1, EFX_QWORD_1, (uint64_t)-1)
-
-#define EFX_SET_OWORD32(_oword) \
+#define EFX_SET_OWORD(_oword) \
EFX_POPULATE_OWORD_4(_oword, \
EFX_DWORD_0, 0xffffffff, EFX_DWORD_1, 0xffffffff, \
EFX_DWORD_2, 0xffffffff, EFX_DWORD_3, 0xffffffff)
@@ -969,11 +972,7 @@ extern int fix_lint;
#define EFX_ZERO_QWORD(_qword) \
EFX_POPULATE_QWORD_1(_qword, EFX_DUMMY_FIELD, 0)
-#define EFX_SET_QWORD64(_qword) \
- EFX_POPULATE_QWORD_1(_qword, \
- EFX_QWORD_0, (uint64_t)-1)
-
-#define EFX_SET_QWORD32(_qword) \
+#define EFX_SET_QWORD(_qword) \
EFX_POPULATE_QWORD_2(_qword, \
EFX_DWORD_0, 0xffffffff, EFX_DWORD_1, 0xffffffff)
@@ -1380,6 +1379,23 @@ extern int fix_lint;
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
+#define EFX_TEST_OWORD_BIT64(_oword, _bit) \
+ (((_oword).eo_u64[0] & \
+ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0)))) || \
+ ((_oword).eo_u64[1] & \
+ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(64)))))
+
+#define EFX_TEST_OWORD_BIT32(_oword, _bit) \
+ (((_oword).eo_u32[0] & \
+ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) || \
+ ((_oword).eo_u32[1] & \
+ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32)))) || \
+ ((_oword).eo_u32[2] & \
+ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(64)))) || \
+ ((_oword).eo_u32[3] & \
+ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(96)))))
+
+
#define EFX_SET_QWORD_BIT64(_qword, _bit) \
do { \
_NOTE(CONSTANTCONDITION) \
@@ -1416,6 +1432,17 @@ extern int fix_lint;
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
+#define EFX_TEST_QWORD_BIT64(_qword, _bit) \
+ (((_qword).eq_u64[0] & \
+ __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0)))) != 0)
+
+#define EFX_TEST_QWORD_BIT32(_qword, _bit) \
+ (((_qword).eq_u32[0] & \
+ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) || \
+ ((_qword).eq_u32[1] & \
+ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32)))))
+
+
#define EFX_SET_DWORD_BIT(_dword, _bit) \
do { \
(_dword).ed_u32[0] |= \
@@ -1430,6 +1457,11 @@ extern int fix_lint;
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
+#define EFX_TEST_DWORD_BIT(_dword, _bit) \
+ (((_dword).ed_u32[0] & \
+ __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) != 0)
+
+
#define EFX_SET_WORD_BIT(_word, _bit) \
do { \
(_word).ew_u16[0] |= \
@@ -1444,6 +1476,11 @@ extern int fix_lint;
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
+#define EFX_TEST_WORD_BIT(_word, _bit) \
+ (((_word).ew_u16[0] & \
+ __CPU_TO_LE_16(EFX_SHIFT16(_bit, FIX_LINT(0)))) != 0)
+
+
#define EFX_SET_BYTE_BIT(_byte, _bit) \
do { \
(_byte).eb_u8[0] |= \
@@ -1458,6 +1495,11 @@ extern int fix_lint;
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
+#define EFX_TEST_BYTE_BIT(_byte, _bit) \
+ (((_byte).eb_u8[0] & \
+ __NATIVE_8(EFX_SHIFT8(_bit, FIX_LINT(0)))) != 0)
+
+
#define EFX_OR_OWORD64(_oword1, _oword2) \
do { \
(_oword1).eo_u64[0] |= (_oword2).eo_u64[0]; \
@@ -1563,18 +1605,18 @@ extern int fix_lint;
#define EFX_QWORD_IS_SET EFX_QWORD_IS_SET64
#define EFX_POPULATE_OWORD EFX_POPULATE_OWORD64
#define EFX_POPULATE_QWORD EFX_POPULATE_QWORD64
-#define EFX_SET_OWORD EFX_SET_OWORD64
-#define EFX_SET_QWORD EFX_SET_QWORD64
#define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD64
#define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD64
#define EFX_SET_OWORD_BIT EFX_SET_OWORD_BIT64
#define EFX_CLEAR_OWORD_BIT EFX_CLEAR_OWORD_BIT64
+#define EFX_TEST_OWORD_BIT EFX_TEST_OWORD_BIT64
#define EFX_SET_QWORD_BIT EFX_SET_QWORD_BIT64
#define EFX_CLEAR_QWORD_BIT EFX_CLEAR_QWORD_BIT64
+#define EFX_TEST_QWORD_BIT EFX_TEST_QWORD_BIT64
#define EFX_OR_OWORD EFX_OR_OWORD64
#define EFX_AND_OWORD EFX_AND_OWORD64
#define EFX_OR_QWORD EFX_OR_QWORD64
-#define EFX_AND_QWORD EFX_OR_QWORD64
+#define EFX_AND_QWORD EFX_AND_QWORD64
#else
#define EFX_OWORD_FIELD EFX_OWORD_FIELD32
#define EFX_QWORD_FIELD EFX_QWORD_FIELD32
@@ -1586,18 +1628,18 @@ extern int fix_lint;
#define EFX_QWORD_IS_SET EFX_QWORD_IS_SET32
#define EFX_POPULATE_OWORD EFX_POPULATE_OWORD32
#define EFX_POPULATE_QWORD EFX_POPULATE_QWORD32
-#define EFX_SET_OWORD EFX_SET_OWORD32
-#define EFX_SET_QWORD EFX_SET_QWORD32
#define EFX_SET_OWORD_FIELD EFX_SET_OWORD_FIELD32
#define EFX_SET_QWORD_FIELD EFX_SET_QWORD_FIELD32
#define EFX_SET_OWORD_BIT EFX_SET_OWORD_BIT32
#define EFX_CLEAR_OWORD_BIT EFX_CLEAR_OWORD_BIT32
+#define EFX_TEST_OWORD_BIT EFX_TEST_OWORD_BIT32
#define EFX_SET_QWORD_BIT EFX_SET_QWORD_BIT32
#define EFX_CLEAR_QWORD_BIT EFX_CLEAR_QWORD_BIT32
+#define EFX_TEST_QWORD_BIT EFX_TEST_QWORD_BIT32
#define EFX_OR_OWORD EFX_OR_OWORD32
#define EFX_AND_OWORD EFX_AND_OWORD32
#define EFX_OR_QWORD EFX_OR_QWORD32
-#define EFX_AND_QWORD EFX_OR_QWORD32
+#define EFX_AND_QWORD EFX_AND_QWORD32
#endif
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/efx_vpd.c b/sys/dev/sfxge/common/efx_vpd.c
index 399c0567efab..812070a66388 100644
--- a/sys/dev/sfxge/common/efx_vpd.c
+++ b/sys/dev/sfxge/common/efx_vpd.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -54,7 +59,7 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_FALCON
-static efx_vpd_ops_t __cs __efx_vpd_falcon_ops = {
+static efx_vpd_ops_t __efx_vpd_falcon_ops = {
NULL, /* evpdo_init */
falcon_vpd_size, /* evpdo_size */
falcon_vpd_read, /* evpdo_read */
@@ -71,7 +76,7 @@ static efx_vpd_ops_t __cs __efx_vpd_falcon_ops = {
#if EFSYS_OPT_SIENA
-static efx_vpd_ops_t __cs __efx_vpd_siena_ops = {
+static efx_vpd_ops_t __efx_vpd_siena_ops = {
siena_vpd_init, /* evpdo_init */
siena_vpd_size, /* evpdo_size */
siena_vpd_read, /* evpdo_read */
@@ -86,6 +91,23 @@ static efx_vpd_ops_t __cs __efx_vpd_siena_ops = {
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+
+static efx_vpd_ops_t __efx_vpd_hunt_ops = {
+ hunt_vpd_init, /* evpdo_init */
+ hunt_vpd_size, /* evpdo_size */
+ hunt_vpd_read, /* evpdo_read */
+ hunt_vpd_verify, /* evpdo_verify */
+ hunt_vpd_reinit, /* evpdo_reinit */
+ hunt_vpd_get, /* evpdo_get */
+ hunt_vpd_set, /* evpdo_set */
+ hunt_vpd_next, /* evpdo_next */
+ hunt_vpd_write, /* evpdo_write */
+ hunt_vpd_fini, /* evpdo_fini */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_vpd_init(
__in efx_nic_t *enp)
@@ -110,6 +132,12 @@ efx_vpd_init(
break;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ evpdop = (efx_vpd_ops_t *)&__efx_vpd_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
default:
EFSYS_ASSERT(0);
rc = ENOTSUP;
@@ -566,14 +594,14 @@ fail1:
return (rc);
}
-static uint8_t __cs __efx_vpd_blank_pid[] = {
+static uint8_t __efx_vpd_blank_pid[] = {
/* Large resource type ID length 1 */
0x82, 0x01, 0x00,
/* Product name ' ' */
0x32,
};
-static uint8_t __cs __efx_vpd_blank_r[] = {
+static uint8_t __efx_vpd_blank_r[] = {
/* Large resource type VPD-R length 4 */
0x90, 0x04, 0x00,
/* RV keyword length 1 */
@@ -584,7 +612,7 @@ static uint8_t __cs __efx_vpd_blank_r[] = {
__checkReturn int
efx_vpd_hunk_reinit(
- __in caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size,
__in boolean_t wantpid)
{
diff --git a/sys/dev/sfxge/common/efx_wol.c b/sys/dev/sfxge/common/efx_wol.c
index 89a80c779f14..2e1b4a169de2 100644
--- a/sys/dev/sfxge/common/efx_wol.c
+++ b/sys/dev/sfxge/common/efx_wol.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -67,17 +72,19 @@ efx_wol_filter_clear(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_WOL_FILTER_RESET_IN_LEN];
+ uint8_t payload[MAX(MC_CMD_WOL_FILTER_RESET_IN_LEN,
+ MC_CMD_WOL_FILTER_RESET_OUT_LEN)];
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_WOL_FILTER_RESET;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN;
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_WOL_FILTER_RESET_OUT_LEN;
MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK,
MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS |
@@ -114,8 +121,8 @@ efx_wol_filter_add(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_WOL_FILTER_SET;
- (void) memset(payload, '\0', sizeof (payload));
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN;
req.emr_out_buf = payload;
@@ -226,18 +233,19 @@ efx_wol_filter_remove(
__in uint32_t filter_id)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_WOL_FILTER_REMOVE_IN_LEN];
+ uint8_t payload[MAX(MC_CMD_WOL_FILTER_REMOVE_IN_LEN,
+ MC_CMD_WOL_FILTER_REMOVE_OUT_LEN)];
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_WOL_FILTER_REMOVE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_WOL_FILTER_REMOVE_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_WOL_FILTER_REMOVE_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_WOL_FILTER_REMOVE_OUT_LEN;
MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id);
@@ -273,6 +281,7 @@ efx_lightsout_offload_add(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_ADD_LIGHTSOUT_OFFLOAD;
req.emr_in_buf = payload;
req.emr_in_length = sizeof (type);
@@ -282,6 +291,7 @@ efx_lightsout_offload_add(
switch (type) {
case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN;
+
MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP);
EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
@@ -292,6 +302,7 @@ efx_lightsout_offload_add(
break;
case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS:
req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN;
+
MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
@@ -305,25 +316,28 @@ efx_lightsout_offload_add(
paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip));
break;
default:
- EFSYS_ASSERT3U(type, !=, type);
+ rc = EINVAL;
+ goto fail1;
}
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
- goto fail1;
+ goto fail2;
}
if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) {
rc = EMSGSIZE;
- goto fail2;
+ goto fail3;
}
*filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID);
return (0);
+fail3:
+ EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
@@ -340,18 +354,19 @@ efx_lightsout_offload_remove(
__in uint32_t filter_id)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN];
+ uint8_t payload[MAX(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN,
+ MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN)];
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD;
req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_in_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN;
switch (type) {
case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
@@ -363,7 +378,8 @@ efx_lightsout_offload_remove(
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
break;
default:
- EFSYS_ASSERT3U(type, !=, type);
+ rc = EINVAL;
+ goto fail1;
}
MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID,
@@ -373,11 +389,13 @@ efx_lightsout_offload_remove(
if (req.emr_rc != 0) {
rc = req.emr_rc;
- goto fail1;
+ goto fail2;
}
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
diff --git a/sys/dev/sfxge/common/hunt_ev.c b/sys/dev/sfxge/common/hunt_ev.c
new file mode 100644
index 000000000000..8e5cf89bc215
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_ev.c
@@ -0,0 +1,1010 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_regs.h"
+#include "efx_impl.h"
+#if EFSYS_OPT_MON_STATS
+#include "mcdi_mon.h"
+#endif
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_QSTATS
+#define EFX_EV_QSTAT_INCR(_eep, _stat) \
+ do { \
+ (_eep)->ee_stat[_stat]++; \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+#else
+#define EFX_EV_QSTAT_INCR(_eep, _stat)
+#endif
+
+
+static __checkReturn boolean_t
+hunt_ev_rx(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static __checkReturn boolean_t
+hunt_ev_tx(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static __checkReturn boolean_t
+hunt_ev_driver(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static __checkReturn boolean_t
+hunt_ev_drv_gen(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static __checkReturn boolean_t
+hunt_ev_mcdi(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+
+static __checkReturn int
+efx_mcdi_init_evq(
+ __in efx_nic_t *enp,
+ __in unsigned int instance,
+ __in efsys_mem_t *esmp,
+ __in size_t nevs,
+ __in uint32_t irq,
+ __out_opt uint32_t *irqp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[
+ MAX(MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
+ MC_CMD_INIT_EVQ_OUT_LEN)];
+ efx_qword_t *dma_addr;
+ uint64_t addr;
+ int npages;
+ int i;
+ int supports_rx_batching;
+ int rc;
+
+ npages = EFX_EVQ_NBUFS(nevs);
+ if (MC_CMD_INIT_EVQ_IN_LEN(npages) > MC_CMD_INIT_EVQ_IN_LENMAX) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_INIT_EVQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_INIT_EVQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_SIZE, nevs);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_INSTANCE, instance);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_IRQ_NUM, irq);
+
+ /*
+ * On Huntington RX and TX event batching can only be requested
+ * together (even if the datapath firmware doesn't actually support RX
+ * batching).
+ * Cut through is incompatible with RX batching and so enabling cut
+ * through disables RX batching (but it does not affect TX batching).
+ *
+ * So always enable RX and TX event batching, and enable cut through
+ * if RX event batching isn't supported (i.e. on low latency firmware).
+ */
+ supports_rx_batching = enp->en_nic_cfg.enc_rx_batching_enabled ? 1 : 0;
+ MCDI_IN_POPULATE_DWORD_6(req, INIT_EVQ_IN_FLAGS,
+ INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
+ INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
+ INIT_EVQ_IN_FLAG_INT_ARMD, 0,
+ INIT_EVQ_IN_FLAG_CUT_THRU, !supports_rx_batching,
+ INIT_EVQ_IN_FLAG_RX_MERGE, 1,
+ INIT_EVQ_IN_FLAG_TX_MERGE, 1);
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_MODE,
+ MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, 0);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, 0);
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_MODE,
+ MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_THRSHLD, 0);
+
+ dma_addr = MCDI_IN2(req, efx_qword_t, INIT_EVQ_IN_DMA_ADDR);
+ addr = EFSYS_MEM_ADDR(esmp);
+
+ for (i = 0; i < npages; i++) {
+ EFX_POPULATE_QWORD_2(*dma_addr,
+ EFX_DWORD_1, (uint32_t)(addr >> 32),
+ EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
+
+ dma_addr++;
+ addr += EFX_BUF_SIZE;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ if (irqp != NULL)
+ *irqp = MCDI_OUT_DWORD(req, INIT_EVQ_OUT_IRQ);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_fini_evq(
+ __in efx_nic_t *enp,
+ __in uint32_t instance)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FINI_EVQ_IN_LEN,
+ MC_CMD_FINI_EVQ_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FINI_EVQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FINI_EVQ_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FINI_EVQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FINI_EVQ_IN_INSTANCE, instance);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+
+ __checkReturn int
+hunt_ev_init(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+ return (0);
+}
+
+ void
+hunt_ev_fini(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+ __checkReturn int
+hunt_ev_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in efx_evq_t *eep)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t irq;
+ int rc;
+
+ _NOTE(ARGUNUSED(id)) /* buftbl id managed by MC */
+ EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
+ EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
+
+ if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (index >= encp->enc_evq_limit) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ /* Set up the handler table */
+ eep->ee_rx = hunt_ev_rx;
+ eep->ee_tx = hunt_ev_tx;
+ eep->ee_driver = hunt_ev_driver;
+ eep->ee_drv_gen = hunt_ev_drv_gen;
+ eep->ee_mcdi = hunt_ev_mcdi;
+
+ /*
+ * Set up the event queue
+ * NOTE: ignore the returned IRQ param as firmware does not set it.
+ */
+ irq = index; /* INIT_EVQ expects function-relative vector number */
+ if ((rc = efx_mcdi_init_evq(enp, index, esmp, n, irq, NULL)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_ev_qdestroy(
+ __in efx_evq_t *eep)
+{
+ efx_nic_t *enp = eep->ee_enp;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) efx_mcdi_fini_evq(eep->ee_enp, eep->ee_index);
+}
+
+ __checkReturn int
+hunt_ev_qprime(
+ __in efx_evq_t *eep,
+ __in unsigned int count)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ uint32_t rptr;
+ efx_dword_t dword;
+
+ rptr = count & eep->ee_mask;
+
+ if (enp->en_nic_cfg.enc_bug35388_workaround) {
+ EFX_STATIC_ASSERT(EFX_EVQ_MINNEVS >
+ (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
+ EFX_STATIC_ASSERT(EFX_EVQ_MAXNEVS <
+ (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
+
+ EFX_POPULATE_DWORD_2(dword,
+ ERF_DD_EVQ_IND_RPTR_FLAGS,
+ EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
+ ERF_DD_EVQ_IND_RPTR,
+ (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH));
+ EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
+ &dword, B_FALSE);
+
+ EFX_POPULATE_DWORD_2(dword,
+ ERF_DD_EVQ_IND_RPTR_FLAGS,
+ EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
+ ERF_DD_EVQ_IND_RPTR,
+ rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
+ EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
+ &dword, B_FALSE);
+ } else {
+ EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr);
+ EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
+ &dword, B_FALSE);
+ }
+
+ return (0);
+}
+
+static __checkReturn int
+efx_mcdi_driver_event(
+ __in efx_nic_t *enp,
+ __in uint32_t evq,
+ __in efx_qword_t data)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_DRIVER_EVENT_IN_LEN,
+ MC_CMD_DRIVER_EVENT_OUT_LEN)];
+ int rc;
+
+ req.emr_cmd = MC_CMD_DRIVER_EVENT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_DRIVER_EVENT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_DRIVER_EVENT_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_EVQ, evq);
+
+ MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_LO,
+ EFX_QWORD_FIELD(data, EFX_DWORD_0));
+ MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_HI,
+ EFX_QWORD_FIELD(data, EFX_DWORD_1));
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_ev_qpost(
+ __in efx_evq_t *eep,
+ __in uint16_t data)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_qword_t event;
+
+ EFX_POPULATE_QWORD_3(event,
+ ESF_DZ_DRV_CODE, ESE_DZ_EV_CODE_DRV_GEN_EV,
+ ESF_DZ_DRV_SUB_CODE, 0,
+ ESF_DZ_DRV_SUB_DATA_DW0, (uint32_t)data);
+
+ (void) efx_mcdi_driver_event(enp, eep->ee_index, event);
+}
+
+ __checkReturn int
+hunt_ev_qmoderate(
+ __in efx_evq_t *eep,
+ __in unsigned int us)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_dword_t dword;
+ uint32_t timer_val, mode;
+ int rc;
+
+ if (us > encp->enc_evq_timer_max_us) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* If the value is zero then disable the timer */
+ if (us == 0) {
+ timer_val = 0;
+ mode = FFE_CZ_TIMER_MODE_DIS;
+ } else {
+ /* Calculate the timer value in quanta */
+ timer_val = us * 1000 / encp->enc_evq_timer_quantum_ns;
+
+ /* Moderation value is base 0 so we need to deduct 1 */
+ if (timer_val > 0)
+ timer_val--;
+
+ mode = FFE_CZ_TIMER_MODE_INT_HLDOFF;
+ }
+
+ if (encp->enc_bug35388_workaround) {
+ EFX_POPULATE_DWORD_3(dword,
+ ERF_DD_EVQ_IND_TIMER_FLAGS,
+ EFE_DD_EVQ_IND_TIMER_FLAGS,
+ ERF_DD_EVQ_IND_TIMER_MODE, mode,
+ ERF_DD_EVQ_IND_TIMER_VAL, timer_val);
+ EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT,
+ eep->ee_index, &dword, 0);
+ } else {
+ EFX_POPULATE_DWORD_2(dword,
+ FRF_CZ_TC_TIMER_MODE, mode,
+ FRF_CZ_TC_TIMER_VAL, timer_val);
+ EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0,
+ eep->ee_index, &dword, 0);
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+#if EFSYS_OPT_QSTATS
+ void
+hunt_ev_qstats_update(
+ __in efx_evq_t *eep,
+ __inout_ecount(EV_NQSTATS) efsys_stat_t *stat)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+ unsigned int id;
+
+ for (id = 0; id < EV_NQSTATS; id++) {
+ efsys_stat_t *essp = &stat[id];
+
+ EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
+ eep->ee_stat[id] = 0;
+ }
+}
+#endif /* EFSYS_OPT_QSTATS */
+
+
+static __checkReturn boolean_t
+hunt_ev_rx(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ uint32_t size;
+ boolean_t parse_err;
+ uint32_t label;
+ uint32_t mcast;
+ uint32_t eth_base_class;
+ uint32_t eth_tag_class;
+ uint32_t l3_class;
+ uint32_t l4_class;
+ uint32_t next_read_lbits;
+ boolean_t soft1, soft2;
+ uint16_t flags;
+ boolean_t should_abort;
+ efx_evq_rxq_state_t *eersp;
+ unsigned int desc_count;
+ unsigned int last_used_id;
+
+ EFX_EV_QSTAT_INCR(eep, EV_RX);
+
+ /* Discard events after RXQ/TXQ errors */
+ if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
+ return (B_FALSE);
+
+ /*
+ * FIXME: likely to be incomplete, incorrect and inefficient.
+ * Improvements in all three areas are required.
+ */
+
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
+ /* Drop this event */
+ return (B_FALSE);
+ }
+ flags = 0;
+
+ size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
+
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT) != 0) {
+ /*
+ * FIXME: There is not yet any driver that supports scatter on
+ * Huntington. Scatter support is required for OSX.
+ */
+ EFSYS_ASSERT(0);
+ flags |= EFX_PKT_CONT;
+ }
+
+ parse_err = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE) != 0);
+ label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
+
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
+ /* Ethernet frame CRC bad */
+ flags |= EFX_DISCARD;
+ }
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC0_ERR) != 0) {
+ /* IP+TCP, bad CRC in iSCSI header */
+ flags |= EFX_DISCARD;
+ }
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC1_ERR) != 0) {
+ /* IP+TCP, bad CRC in iSCSI payload or FCoE or FCoIP */
+ flags |= EFX_DISCARD;
+ }
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
+ /* ECC memory error */
+ flags |= EFX_DISCARD;
+ }
+
+ /* FIXME: do we need soft bits from RXDP firmware ? */
+ soft1 = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_SOFT1) != 0);
+ soft2 = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_SOFT2) != 0);
+
+ mcast = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
+ if (mcast == ESE_DZ_MAC_CLASS_UCAST)
+ flags |= EFX_PKT_UNICAST;
+
+ eth_base_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_BASE_CLASS);
+ eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
+ l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
+ l4_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L4_CLASS);
+
+ /* bottom 4 bits of incremented index (not last desc consumed) */
+ next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
+
+ /* Increment the count of descriptors read */
+ eersp = &eep->ee_rxq_state[label];
+ desc_count = (next_read_lbits - eersp->eers_rx_read_ptr) &
+ EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
+ eersp->eers_rx_read_ptr += desc_count;
+
+ /*
+ * FIXME: add error checking to make sure this a batched event.
+ * This could also be an aborted scatter, see Bug36629.
+ */
+ if (desc_count > 1) {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
+ flags |= EFX_PKT_PREFIX_LEN;
+ }
+
+ /* Calculate the index of the the last descriptor consumed */
+ last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
+
+ /* EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_OVERRIDE_HOLDOFF); */
+
+ switch (eth_base_class) {
+ case ESE_DZ_ETH_BASE_CLASS_LLC_SNAP:
+ case ESE_DZ_ETH_BASE_CLASS_LLC:
+ case ESE_DZ_ETH_BASE_CLASS_ETH2:
+ default:
+ break;
+ }
+
+ switch (eth_tag_class) {
+ case ESE_DZ_ETH_TAG_CLASS_RSVD7:
+ case ESE_DZ_ETH_TAG_CLASS_RSVD6:
+ case ESE_DZ_ETH_TAG_CLASS_RSVD5:
+ case ESE_DZ_ETH_TAG_CLASS_RSVD4:
+ break;
+
+ case ESE_DZ_ETH_TAG_CLASS_RSVD3: /* Triple tagged */
+ case ESE_DZ_ETH_TAG_CLASS_VLAN2: /* Double tagged */
+ case ESE_DZ_ETH_TAG_CLASS_VLAN1: /* VLAN tagged */
+ flags |= EFX_PKT_VLAN_TAGGED;
+ break;
+
+ case ESE_DZ_ETH_TAG_CLASS_NONE:
+ default:
+ break;
+ }
+
+ switch (l3_class) {
+ case ESE_DZ_L3_CLASS_RSVD7: /* Used by firmware for packet overrun */
+ parse_err = B_TRUE;
+ flags |= EFX_DISCARD;
+ break;
+
+ case ESE_DZ_L3_CLASS_ARP:
+ case ESE_DZ_L3_CLASS_FCOE:
+ break;
+
+ case ESE_DZ_L3_CLASS_IP6_FRAG:
+ case ESE_DZ_L3_CLASS_IP6:
+ flags |= EFX_PKT_IPV6;
+ break;
+
+ case ESE_DZ_L3_CLASS_IP4_FRAG:
+ case ESE_DZ_L3_CLASS_IP4:
+ flags |= EFX_PKT_IPV4;
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR) == 0)
+ flags |= EFX_CKSUM_IPV4;
+ break;
+
+ case ESE_DZ_L3_CLASS_UNKNOWN:
+ default:
+ break;
+ }
+
+ switch (l4_class) {
+ case ESE_DZ_L4_CLASS_RSVD7:
+ case ESE_DZ_L4_CLASS_RSVD6:
+ case ESE_DZ_L4_CLASS_RSVD5:
+ case ESE_DZ_L4_CLASS_RSVD4:
+ case ESE_DZ_L4_CLASS_RSVD3:
+ break;
+
+ case ESE_DZ_L4_CLASS_UDP:
+ flags |= EFX_PKT_UDP;
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
+ flags |= EFX_CKSUM_TCPUDP;
+ break;
+
+ case ESE_DZ_L4_CLASS_TCP:
+ flags |= EFX_PKT_TCP;
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
+ flags |= EFX_CKSUM_TCPUDP;
+ break;
+
+ case ESE_DZ_L4_CLASS_UNKNOWN:
+ default:
+ break;
+ }
+
+ /* If we're not discarding the packet then it is ok */
+ if (~flags & EFX_DISCARD)
+ EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
+
+ EFSYS_ASSERT(eecp->eec_rx != NULL);
+ should_abort = eecp->eec_rx(arg, label, last_used_id, size, flags);
+
+ return (should_abort);
+}
+
+static __checkReturn boolean_t
+hunt_ev_tx(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ uint32_t id;
+ uint32_t label;
+ boolean_t should_abort;
+
+ EFX_EV_QSTAT_INCR(eep, EV_TX);
+
+ /* Discard events after RXQ/TXQ errors */
+ if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
+ return (B_FALSE);
+
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
+ /* Drop this event */
+ return (B_FALSE);
+ }
+
+ /* Per-packet TX completion (was per-descriptor for Falcon/Siena) */
+ id = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DESCR_INDX);
+ label = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_QLABEL);
+
+ EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
+
+ EFSYS_ASSERT(eecp->eec_tx != NULL);
+ should_abort = eecp->eec_tx(arg, label, id);
+
+ return (should_abort);
+}
+
+static __checkReturn boolean_t
+hunt_ev_driver(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ unsigned int code;
+ boolean_t should_abort;
+
+ EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
+ should_abort = B_FALSE;
+
+ code = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_CODE);
+ switch (code) {
+ case ESE_DZ_DRV_TIMER_EV: {
+ uint32_t id;
+
+ id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_TMR_ID);
+
+ EFSYS_ASSERT(eecp->eec_timer != NULL);
+ should_abort = eecp->eec_timer(arg, id);
+ break;
+ }
+
+ case ESE_DZ_DRV_WAKE_UP_EV: {
+ uint32_t id;
+
+ id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_EVQ_ID);
+
+ EFSYS_ASSERT(eecp->eec_wake_up != NULL);
+ should_abort = eecp->eec_wake_up(arg, id);
+ break;
+ }
+
+ case ESE_DZ_DRV_START_UP_EV:
+ EFSYS_ASSERT(eecp->eec_initialized != NULL);
+ should_abort = eecp->eec_initialized(arg);
+ break;
+
+ default:
+ EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
+ break;
+ }
+
+ return (should_abort);
+}
+
+static __checkReturn boolean_t
+hunt_ev_drv_gen(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ uint32_t data;
+ boolean_t should_abort;
+
+ EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
+ should_abort = B_FALSE;
+
+ data = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_DATA_DW0);
+ if (data >= ((uint32_t)1 << 16)) {
+ EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
+
+ return (B_TRUE);
+ }
+
+ EFSYS_ASSERT(eecp->eec_software != NULL);
+ should_abort = eecp->eec_software(arg, (uint16_t)data);
+
+ return (should_abort);
+}
+
+static __checkReturn boolean_t
+hunt_ev_mcdi(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ unsigned code;
+ boolean_t should_abort = B_FALSE;
+
+ EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
+
+ code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
+ switch (code) {
+ case MCDI_EVENT_CODE_BADSSERT:
+ efx_mcdi_ev_death(enp, EINTR);
+ break;
+
+ case MCDI_EVENT_CODE_CMDDONE:
+ efx_mcdi_ev_cpl(enp,
+ MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
+ MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
+ MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
+ break;
+
+ case MCDI_EVENT_CODE_LINKCHANGE: {
+ efx_link_mode_t link_mode;
+
+ hunt_phy_link_ev(enp, eqp, &link_mode);
+ should_abort = eecp->eec_link_change(arg, link_mode);
+ break;
+ }
+
+ case MCDI_EVENT_CODE_SENSOREVT: {
+#if EFSYS_OPT_MON_STATS
+ efx_mon_stat_t id;
+ efx_mon_stat_value_t value;
+ int rc;
+
+ /* Decode monitor stat for MCDI sensor (if supported) */
+ if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) {
+ /* Report monitor stat change */
+ should_abort = eecp->eec_monitor(arg, id, value);
+ } else if (rc == ENOTSUP) {
+ should_abort = eecp->eec_exception(arg,
+ EFX_EXCEPTION_UNKNOWN_SENSOREVT,
+ MCDI_EV_FIELD(eqp, DATA));
+ } else {
+ EFSYS_ASSERT(rc == ENODEV); /* Wrong port */
+ }
+#endif
+ break;
+ }
+
+ case MCDI_EVENT_CODE_SCHEDERR:
+ /* Informational only */
+ break;
+
+ case MCDI_EVENT_CODE_REBOOT:
+ /* Falcon/Siena only (should not been seen with Huntington). */
+ efx_mcdi_ev_death(enp, EIO);
+ break;
+
+ case MCDI_EVENT_CODE_MC_REBOOT:
+ /* MC_REBOOT event is used for Huntington (EF10) and later. */
+ efx_mcdi_ev_death(enp, EIO);
+ break;
+
+ case MCDI_EVENT_CODE_MAC_STATS_DMA:
+#if EFSYS_OPT_MAC_STATS
+ if (eecp->eec_mac_stats != NULL) {
+ eecp->eec_mac_stats(arg,
+ MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION));
+ }
+#endif
+ break;
+
+ case MCDI_EVENT_CODE_FWALERT: {
+ uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
+
+ if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
+ should_abort = eecp->eec_exception(arg,
+ EFX_EXCEPTION_FWALERT_SRAM,
+ MCDI_EV_FIELD(eqp, FWALERT_DATA));
+ else
+ should_abort = eecp->eec_exception(arg,
+ EFX_EXCEPTION_UNKNOWN_FWALERT,
+ MCDI_EV_FIELD(eqp, DATA));
+ break;
+ }
+
+ case MCDI_EVENT_CODE_TX_ERR: {
+ /*
+ * After a TXQ error is detected, firmware sends a TX_ERR event.
+ * This may be followed by TX completions (which we discard),
+ * and then finally by a TX_FLUSH event. Firmware destroys the
+ * TXQ automatically after sending the TX_FLUSH event.
+ */
+ enp->en_reset_flags |= EFX_RESET_TXQ_ERR;
+
+ EFSYS_PROBE1(tx_descq_err, uint32_t, MCDI_EV_FIELD(eqp, DATA));
+
+ /* Inform the driver that a reset is required. */
+ eecp->eec_exception(arg, EFX_EXCEPTION_TX_ERROR,
+ MCDI_EV_FIELD(eqp, TX_ERR_DATA));
+ break;
+ }
+
+ case MCDI_EVENT_CODE_TX_FLUSH: {
+ uint32_t txq_index = MCDI_EV_FIELD(eqp, TX_FLUSH_TXQ);
+
+ /*
+ * EF10 firmware sends two TX_FLUSH events: one to the txq's
+ * event queue, and one to evq 0 (with TX_FLUSH_TO_DRIVER set).
+ * We want to wait for all completions, so ignore the events
+ * with TX_FLUSH_TO_DRIVER.
+ */
+ if (MCDI_EV_FIELD(eqp, TX_FLUSH_TO_DRIVER) != 0) {
+ should_abort = B_FALSE;
+ break;
+ }
+
+ EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
+
+ EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
+
+ EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
+ should_abort = eecp->eec_txq_flush_done(arg, txq_index);
+ break;
+ }
+
+ case MCDI_EVENT_CODE_RX_ERR: {
+ /*
+ * After an RXQ error is detected, firmware sends an RX_ERR
+ * event. This may be followed by RX events (which we discard),
+ * and then finally by an RX_FLUSH event. Firmware destroys the
+ * RXQ automatically after sending the RX_FLUSH event.
+ */
+ enp->en_reset_flags |= EFX_RESET_RXQ_ERR;
+
+ EFSYS_PROBE1(rx_descq_err, uint32_t, MCDI_EV_FIELD(eqp, DATA));
+
+ /* Inform the driver that a reset is required. */
+ eecp->eec_exception(arg, EFX_EXCEPTION_RX_ERROR,
+ MCDI_EV_FIELD(eqp, RX_ERR_DATA));
+ break;
+ }
+
+ case MCDI_EVENT_CODE_RX_FLUSH: {
+ uint32_t rxq_index = MCDI_EV_FIELD(eqp, RX_FLUSH_RXQ);
+
+ /*
+ * EF10 firmware sends two RX_FLUSH events: one to the rxq's
+ * event queue, and one to evq 0 (with RX_FLUSH_TO_DRIVER set).
+ * We want to wait for all completions, so ignore the events
+ * with RX_FLUSH_TO_DRIVER.
+ */
+ if (MCDI_EV_FIELD(eqp, RX_FLUSH_TO_DRIVER) != 0) {
+ should_abort = B_FALSE;
+ break;
+ }
+
+ EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
+
+ EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
+
+ EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
+ should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
+ break;
+ }
+
+ default:
+ EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
+ break;
+ }
+
+ return (should_abort);
+}
+
+ void
+hunt_ev_rxlabel_init(
+ __in efx_evq_t *eep,
+ __in efx_rxq_t *erp,
+ __in unsigned int label)
+{
+ efx_evq_rxq_state_t *eersp;
+
+ EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
+ eersp = &eep->ee_rxq_state[label];
+
+ EFSYS_ASSERT3U(eersp->eers_rx_mask, ==, 0);
+
+ eersp->eers_rx_read_ptr = 0;
+ eersp->eers_rx_mask = erp->er_mask;
+}
+
+ void
+hunt_ev_rxlabel_fini(
+ __in efx_evq_t *eep,
+ __in unsigned int label)
+{
+ efx_evq_rxq_state_t *eersp;
+
+ EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
+ eersp = &eep->ee_rxq_state[label];
+
+ EFSYS_ASSERT3U(eersp->eers_rx_mask, !=, 0);
+
+ eersp->eers_rx_read_ptr = 0;
+ eersp->eers_rx_mask = 0;
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_filter.c b/sys/dev/sfxge/common/hunt_filter.c
new file mode 100644
index 000000000000..27af7c343f2d
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_filter.c
@@ -0,0 +1,1376 @@
+/*-
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_regs_mcdi.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_FILTER
+
+#define HFE_SPEC(hftp, index) ((hftp)->hft_entry[(index)].hfe_spec)
+
+static efx_filter_spec_t *
+hunt_filter_entry_spec(
+ __in const hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ return ((efx_filter_spec_t *)(HFE_SPEC(hftp, index) &
+ ~(uintptr_t)EFX_HUNT_FILTER_FLAGS));
+}
+
+static boolean_t
+hunt_filter_entry_is_busy(
+ __in const hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ if (HFE_SPEC(hftp, index) & EFX_HUNT_FILTER_FLAG_BUSY)
+ return (B_TRUE);
+ else
+ return (B_FALSE);
+}
+
+static boolean_t
+hunt_filter_entry_is_auto_old(
+ __in const hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ if (HFE_SPEC(hftp, index) & EFX_HUNT_FILTER_FLAG_AUTO_OLD)
+ return (B_TRUE);
+ else
+ return (B_FALSE);
+}
+
+static void
+hunt_filter_set_entry(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index,
+ __in_opt const efx_filter_spec_t *efsp)
+{
+ HFE_SPEC(hftp, index) = (uintptr_t)efsp;
+}
+
+static void
+hunt_filter_set_entry_busy(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ HFE_SPEC(hftp, index) |= (uintptr_t)EFX_HUNT_FILTER_FLAG_BUSY;
+}
+
+static void
+hunt_filter_set_entry_not_busy(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ HFE_SPEC(hftp, index) &= ~(uintptr_t)EFX_HUNT_FILTER_FLAG_BUSY;
+}
+
+static void
+hunt_filter_set_entry_auto_old(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ EFSYS_ASSERT(hunt_filter_entry_spec(hftp, index) != NULL);
+ HFE_SPEC(hftp, index) |= (uintptr_t)EFX_HUNT_FILTER_FLAG_AUTO_OLD;
+}
+
+static void
+hunt_filter_set_entry_not_auto_old(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ HFE_SPEC(hftp, index) &= ~(uintptr_t)EFX_HUNT_FILTER_FLAG_AUTO_OLD;
+ EFSYS_ASSERT(hunt_filter_entry_spec(hftp, index) != NULL);
+}
+
+ __checkReturn int
+hunt_filter_init(
+ __in efx_nic_t *enp)
+{
+ int rc;
+ hunt_filter_table_t *hftp;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+#define MATCH_MASK(match) (EFX_MASK32(match) << EFX_LOW_BIT(match))
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_REM_HOST ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_SRC_IP));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_LOC_HOST ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_DST_IP));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_REM_MAC ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_SRC_MAC));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_REM_PORT ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_SRC_PORT));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_LOC_MAC ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_DST_MAC));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_LOC_PORT ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_DST_PORT));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_ETHER_TYPE ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_ETHER_TYPE));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_INNER_VID ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_INNER_VLAN));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_OUTER_VID ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_OUTER_VLAN));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_IP_PROTO ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_IP_PROTO));
+#undef MATCH_MASK
+
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (hunt_filter_table_t), hftp);
+
+ if (!hftp) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+
+ enp->en_filter.ef_hunt_filter_table = hftp;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_filter_fini(
+ __in efx_nic_t *enp)
+{
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ if (enp->en_filter.ef_hunt_filter_table != NULL) {
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (hunt_filter_table_t),
+ enp->en_filter.ef_hunt_filter_table);
+ }
+}
+
+static __checkReturn int
+efx_mcdi_filter_op_add(
+ __in efx_nic_t *enp,
+ __in efx_filter_spec_t *spec,
+ __in unsigned int filter_op,
+ __inout hunt_filter_handle_t *handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FILTER_OP_IN_LEN,
+ MC_CMD_FILTER_OP_OUT_LEN)];
+ uint32_t match_fields = 0;
+ int rc;
+
+ memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FILTER_OP;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FILTER_OP_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FILTER_OP_OUT_LEN;
+
+ switch (filter_op) {
+ case MC_CMD_FILTER_OP_IN_OP_REPLACE:
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_LO,
+ handle->hfh_lo);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_HI,
+ handle->hfh_hi);
+ /* Fall through */
+ case MC_CMD_FILTER_OP_IN_OP_INSERT:
+ case MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE:
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_OP, filter_op);
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (spec->efs_match_flags & EFX_FILTER_MATCH_LOC_MAC_IG) {
+ /*
+ * The LOC_MAC_IG match flag can represent unknown unicast
+ * or multicast filters - use the MAC address to distinguish
+ * them.
+ */
+ if (EFX_MAC_ADDR_IS_MULTICAST(spec->efs_loc_mac))
+ match_fields |= 1U <<
+ MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN;
+ else
+ match_fields |= 1U <<
+ MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN;
+ }
+
+ match_fields |= spec->efs_match_flags & (~EFX_FILTER_MATCH_LOC_MAC_IG);
+
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_PORT_ID,
+ EVB_PORT_ID_ASSIGNED);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_MATCH_FIELDS,
+ match_fields);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_RX_DEST,
+ MC_CMD_FILTER_OP_IN_RX_DEST_HOST);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_RX_QUEUE,
+ spec->efs_dmaq_id);
+ if (spec->efs_flags & EFX_FILTER_FLAG_RX_RSS) {
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_RX_CONTEXT,
+ spec->efs_rss_context);
+ }
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_RX_MODE,
+ spec->efs_flags & EFX_FILTER_FLAG_RX_RSS ?
+ MC_CMD_FILTER_OP_IN_RX_MODE_RSS :
+ MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_TX_DEST,
+ MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT);
+
+ if (filter_op != MC_CMD_FILTER_OP_IN_OP_REPLACE) {
+ /*
+ * NOTE: Unlike most MCDI requests, the filter fields
+ * are presented in network (big endian) byte order.
+ */
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_IN_SRC_MAC),
+ spec->efs_rem_mac, EFX_MAC_ADDR_LEN);
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_IN_DST_MAC),
+ spec->efs_loc_mac, EFX_MAC_ADDR_LEN);
+
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_SRC_PORT,
+ __CPU_TO_BE_16(spec->efs_rem_port));
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_DST_PORT,
+ __CPU_TO_BE_16(spec->efs_loc_port));
+
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_ETHER_TYPE,
+ __CPU_TO_BE_16(spec->efs_ether_type));
+
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_INNER_VLAN,
+ __CPU_TO_BE_16(spec->efs_inner_vid));
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_OUTER_VLAN,
+ __CPU_TO_BE_16(spec->efs_outer_vid));
+
+ /* IP protocol (in low byte, high byte is zero) */
+ MCDI_IN_SET_BYTE(req, FILTER_OP_IN_IP_PROTO,
+ spec->efs_ip_proto);
+
+ EFX_STATIC_ASSERT(sizeof (spec->efs_rem_host) ==
+ MC_CMD_FILTER_OP_IN_SRC_IP_LEN);
+ EFX_STATIC_ASSERT(sizeof (spec->efs_loc_host) ==
+ MC_CMD_FILTER_OP_IN_DST_IP_LEN);
+
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_IN_SRC_IP),
+ &spec->efs_rem_host.eo_byte[0],
+ MC_CMD_FILTER_OP_IN_SRC_IP_LEN);
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_IN_DST_IP),
+ &spec->efs_loc_host.eo_byte[0],
+ MC_CMD_FILTER_OP_IN_DST_IP_LEN);
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_FILTER_OP_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ handle->hfh_lo = MCDI_OUT_DWORD(req, FILTER_OP_OUT_HANDLE_LO);
+ handle->hfh_hi = MCDI_OUT_DWORD(req, FILTER_OP_OUT_HANDLE_HI);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
+
+static __checkReturn int
+efx_mcdi_filter_op_delete(
+ __in efx_nic_t *enp,
+ __in unsigned int filter_op,
+ __inout hunt_filter_handle_t *handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FILTER_OP_IN_LEN,
+ MC_CMD_FILTER_OP_OUT_LEN)];
+ int rc;
+
+ memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FILTER_OP;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FILTER_OP_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FILTER_OP_OUT_LEN;
+
+ switch (filter_op) {
+ case MC_CMD_FILTER_OP_IN_OP_REMOVE:
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_OP,
+ MC_CMD_FILTER_OP_IN_OP_REMOVE);
+ break;
+ case MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE:
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_OP,
+ MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE);
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_LO, handle->hfh_lo);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_HI, handle->hfh_hi);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_FILTER_OP_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn boolean_t
+hunt_filter_equal(
+ __in const efx_filter_spec_t *left,
+ __in const efx_filter_spec_t *right)
+{
+ /* FIXME: Consider rx vs tx filters (look at efs_flags) */
+ if (left->efs_match_flags != right->efs_match_flags)
+ return (B_FALSE);
+ if (!EFX_OWORD_IS_EQUAL(left->efs_rem_host, right->efs_rem_host))
+ return (B_FALSE);
+ if (!EFX_OWORD_IS_EQUAL(left->efs_loc_host, right->efs_loc_host))
+ return (B_FALSE);
+ if (memcmp(left->efs_rem_mac, right->efs_rem_mac, EFX_MAC_ADDR_LEN))
+ return (B_FALSE);
+ if (memcmp(left->efs_loc_mac, right->efs_loc_mac, EFX_MAC_ADDR_LEN))
+ return (B_FALSE);
+ if (left->efs_rem_port != right->efs_rem_port)
+ return (B_FALSE);
+ if (left->efs_loc_port != right->efs_loc_port)
+ return (B_FALSE);
+ if (left->efs_inner_vid != right->efs_inner_vid)
+ return (B_FALSE);
+ if (left->efs_outer_vid != right->efs_outer_vid)
+ return (B_FALSE);
+ if (left->efs_ether_type != right->efs_ether_type)
+ return (B_FALSE);
+ if (left->efs_ip_proto != right->efs_ip_proto)
+ return (B_FALSE);
+
+ return (B_TRUE);
+
+}
+
+static __checkReturn boolean_t
+hunt_filter_same_dest(
+ __in const efx_filter_spec_t *left,
+ __in const efx_filter_spec_t *right)
+{
+ if ((left->efs_flags & EFX_FILTER_FLAG_RX_RSS) &&
+ (right->efs_flags & EFX_FILTER_FLAG_RX_RSS)) {
+ if (left->efs_rss_context == right->efs_rss_context)
+ return (B_TRUE);
+ } else if ((~(left->efs_flags) & EFX_FILTER_FLAG_RX_RSS) &&
+ (~(right->efs_flags) & EFX_FILTER_FLAG_RX_RSS)) {
+ if (left->efs_dmaq_id == right->efs_dmaq_id)
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+
+static __checkReturn uint32_t
+hunt_filter_hash(
+ __in efx_filter_spec_t *spec)
+{
+ EFX_STATIC_ASSERT((sizeof (efx_filter_spec_t) % sizeof (uint32_t))
+ == 0);
+ EFX_STATIC_ASSERT((EFX_FIELD_OFFSET(efx_filter_spec_t, efs_outer_vid) %
+ sizeof (uint32_t)) == 0);
+
+ /*
+ * As the area of the efx_filter_spec_t we need to hash is DWORD
+ * aligned and an exact number of DWORDs in size we can use the
+ * optimised efx_hash_dwords() rather than efx_hash_bytes()
+ */
+ return (efx_hash_dwords((const uint32_t *)&spec->efs_outer_vid,
+ (sizeof (efx_filter_spec_t) -
+ EFX_FIELD_OFFSET(efx_filter_spec_t, efs_outer_vid)) /
+ sizeof (uint32_t), 0));
+}
+
+/*
+ * Decide whether a filter should be exclusive or else should allow
+ * delivery to additional recipients. Currently we decide that
+ * filters for specific local unicast MAC and IP addresses are
+ * exclusive.
+ */
+static __checkReturn boolean_t
+hunt_filter_is_exclusive(
+ __in efx_filter_spec_t *spec)
+{
+ if ((spec->efs_match_flags & EFX_FILTER_MATCH_LOC_MAC) &&
+ !EFX_MAC_ADDR_IS_MULTICAST(spec->efs_loc_mac))
+ return (B_TRUE);
+
+ if ((spec->efs_match_flags &
+ (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_HOST)) ==
+ (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_HOST)) {
+ if ((spec->efs_ether_type == EFX_ETHER_TYPE_IPV4) &&
+ ((spec->efs_loc_host.eo_u8[0] & 0xf) != 0xe))
+ return (B_TRUE);
+ if ((spec->efs_ether_type == EFX_ETHER_TYPE_IPV6) &&
+ (spec->efs_loc_host.eo_u8[0] != 0xff))
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+ __checkReturn int
+hunt_filter_restore(
+ __in efx_nic_t *enp)
+{
+ int tbl_id;
+ efx_filter_spec_t *spec;
+ hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
+ boolean_t restoring;
+ int state;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ for (tbl_id = 0; tbl_id < EFX_HUNT_FILTER_TBL_ROWS; tbl_id++) {
+
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ spec = hunt_filter_entry_spec(hftp, tbl_id);
+ if (spec == NULL) {
+ restoring = B_FALSE;
+ } else if (hunt_filter_entry_is_busy(hftp, tbl_id)) {
+ /* Ignore busy entries. */
+ restoring = B_FALSE;
+ } else {
+ hunt_filter_set_entry_busy(hftp, tbl_id);
+ restoring = B_TRUE;
+ }
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ if (restoring == B_FALSE)
+ continue;
+
+ if (hunt_filter_is_exclusive(spec)) {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_INSERT,
+ &hftp->hft_entry[tbl_id].hfe_handle);
+ } else {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE,
+ &hftp->hft_entry[tbl_id].hfe_handle);
+ }
+
+ if (rc != 0)
+ goto fail1;
+
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ hunt_filter_set_entry_not_busy(hftp, tbl_id);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * An arbitrary search limit for the software hash table. As per the linux net
+ * driver.
+ */
+#define EFX_HUNT_FILTER_SEARCH_LIMIT 200
+
+static __checkReturn int
+hunt_filter_add_internal(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec,
+ __in boolean_t may_replace,
+ __out_opt uint32_t *filter_id)
+{
+ int rc;
+ hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t *saved_spec;
+ uint32_t hash;
+ unsigned int depth;
+ int ins_index;
+ boolean_t replacing = B_FALSE;
+ unsigned int i;
+ int state;
+ boolean_t locked = B_FALSE;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+#if EFSYS_OPT_RX_SCALE
+ spec->efs_rss_context = enp->en_rss_context;
+#endif
+
+ hash = hunt_filter_hash(spec);
+
+ /*
+ * FIXME: Add support for inserting filters of different priorities
+ * and removing lower priority multicast filters (bug 42378)
+ */
+
+ /*
+ * Find any existing filters with the same match tuple or
+ * else a free slot to insert at. If any of them are busy,
+ * we have to wait and retry.
+ */
+ for (;;) {
+ ins_index = -1;
+ depth = 1;
+ EFSYS_LOCK(enp->en_eslp, state);
+ locked = B_TRUE;
+
+ for (;;) {
+ i = (hash + depth) & (EFX_HUNT_FILTER_TBL_ROWS - 1);
+ saved_spec = hunt_filter_entry_spec(hftp, i);
+
+ if (!saved_spec) {
+ if (ins_index < 0) {
+ ins_index = i;
+ }
+ } else if (hunt_filter_equal(spec, saved_spec)) {
+ if (hunt_filter_entry_is_busy(hftp, i))
+ break;
+ if (saved_spec->efs_priority
+ == EFX_FILTER_PRI_AUTO) {
+ ins_index = i;
+ goto found;
+ } else if (hunt_filter_is_exclusive(spec)) {
+ if (may_replace) {
+ ins_index = i;
+ goto found;
+ } else {
+ rc = EEXIST;
+ goto fail1;
+ }
+ }
+
+ /* Leave existing */
+ }
+
+ /*
+ * Once we reach the maximum search depth, use
+ * the first suitable slot or return EBUSY if
+ * there was none.
+ */
+ if (depth == EFX_HUNT_FILTER_SEARCH_LIMIT) {
+ if (ins_index < 0) {
+ rc = EBUSY;
+ goto fail2;
+ }
+ goto found;
+ }
+ depth++;
+ }
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+ }
+
+found:
+ /*
+ * Create a software table entry if necessary, and mark it
+ * busy. We might yet fail to insert, but any attempt to
+ * insert a conflicting filter while we're waiting for the
+ * firmware must find the busy entry.
+ */
+ saved_spec = hunt_filter_entry_spec(hftp, ins_index);
+ if (saved_spec) {
+ if (saved_spec->efs_priority == EFX_FILTER_PRI_AUTO) {
+ /* This is a filter we are refreshing */
+ hunt_filter_set_entry_not_auto_old(hftp, ins_index);
+ goto out_unlock;
+
+ }
+ replacing = B_TRUE;
+ } else {
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (*spec), saved_spec);
+ if (!saved_spec) {
+ rc = ENOMEM;
+ goto fail3;
+ }
+ *saved_spec = *spec;
+ hunt_filter_set_entry(hftp, ins_index, saved_spec);
+ }
+ hunt_filter_set_entry_busy(hftp, ins_index);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+
+ /*
+ * On replacing the filter handle may change after after a successful
+ * replace operation.
+ */
+ if (replacing) {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_REPLACE,
+ &hftp->hft_entry[ins_index].hfe_handle);
+ } else if (hunt_filter_is_exclusive(spec)) {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_INSERT,
+ &hftp->hft_entry[ins_index].hfe_handle);
+ } else {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE,
+ &hftp->hft_entry[ins_index].hfe_handle);
+ }
+
+ if (rc != 0)
+ goto fail4;
+
+ EFSYS_LOCK(enp->en_eslp, state);
+ locked = B_TRUE;
+
+ if (replacing) {
+ /* Update the fields that may differ */
+ saved_spec->efs_priority = spec->efs_priority;
+ saved_spec->efs_flags = spec->efs_flags;
+ saved_spec->efs_rss_context = spec->efs_rss_context;
+ saved_spec->efs_dmaq_id = spec->efs_dmaq_id;
+ }
+
+ hunt_filter_set_entry_not_busy(hftp, ins_index);
+
+out_unlock:
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+
+ if (filter_id)
+ *filter_id = ins_index;
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+
+ if (!replacing) {
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (*spec), saved_spec);
+ saved_spec = NULL;
+ }
+ hunt_filter_set_entry_not_busy(hftp, ins_index);
+ hunt_filter_set_entry(hftp, ins_index, NULL);
+
+fail3:
+ EFSYS_PROBE(fail3);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ if (locked)
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_filter_add(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec,
+ __in boolean_t may_replace)
+{
+ int rc;
+
+ rc = hunt_filter_add_internal(enp, spec, may_replace, NULL);
+ if (rc != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+hunt_filter_delete_internal(
+ __in efx_nic_t *enp,
+ __in uint32_t filter_id)
+{
+ int rc;
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t *spec;
+ int state;
+ uint32_t filter_idx = filter_id % EFX_HUNT_FILTER_TBL_ROWS;
+
+ /*
+ * Find the software table entry and mark it busy. Don't
+ * remove it yet; any attempt to update while we're waiting
+ * for the firmware must find the busy entry.
+ *
+ * FIXME: What if the busy flag is never cleared?
+ */
+ EFSYS_LOCK(enp->en_eslp, state);
+ while (hunt_filter_entry_is_busy(table, filter_idx)) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ EFSYS_SPIN(1);
+ EFSYS_LOCK(enp->en_eslp, state);
+ }
+ if ((spec = hunt_filter_entry_spec(table, filter_idx)) != NULL) {
+ hunt_filter_set_entry_busy(table, filter_idx);
+ }
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ if (spec == NULL) {
+ rc = ENOENT;
+ goto fail1;
+ }
+
+ /*
+ * Try to remove the hardware filter. This may fail if the MC has
+ * rebooted (which frees all hardware filter resources).
+ */
+ if (hunt_filter_is_exclusive(spec)) {
+ rc = efx_mcdi_filter_op_delete(enp,
+ MC_CMD_FILTER_OP_IN_OP_REMOVE,
+ &table->hft_entry[filter_idx].hfe_handle);
+ } else {
+ rc = efx_mcdi_filter_op_delete(enp,
+ MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE,
+ &table->hft_entry[filter_idx].hfe_handle);
+ }
+
+ /* Free the software table entry */
+ EFSYS_LOCK(enp->en_eslp, state);
+ hunt_filter_set_entry_not_busy(table, filter_idx);
+ hunt_filter_set_entry(table, filter_idx, NULL);
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (*spec), spec);
+
+ /* Check result of hardware filter removal */
+ if (rc != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_filter_delete(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec)
+{
+ int rc;
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t *saved_spec;
+ unsigned int hash;
+ unsigned int depth;
+ unsigned int i;
+ int state;
+ boolean_t locked = B_FALSE;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ hash = hunt_filter_hash(spec);
+
+ EFSYS_LOCK(enp->en_eslp, state);
+ locked = B_TRUE;
+
+ depth = 1;
+ for (;;) {
+ i = (hash + depth) & (EFX_HUNT_FILTER_TBL_ROWS - 1);
+ saved_spec = hunt_filter_entry_spec(table, i);
+ if (saved_spec && hunt_filter_equal(spec, saved_spec) &&
+ hunt_filter_same_dest(spec, saved_spec)) {
+ break;
+ }
+ if (depth == EFX_HUNT_FILTER_SEARCH_LIMIT) {
+ rc = ENOENT;
+ goto fail1;
+ }
+ depth++;
+ }
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+
+ rc = hunt_filter_delete_internal(enp, i);
+ if (rc != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ if (locked)
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_parser_disp_info(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PARSER_DISP_INFO_IN_LEN,
+ MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX)];
+ int rc;
+ uint32_t i;
+ boolean_t support_unknown_ucast = B_FALSE;
+ boolean_t support_unknown_mcast = B_FALSE;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PARSER_DISP_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PARSER_DISP_INFO_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, GET_PARSER_DISP_INFO_OUT_OP,
+ MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ *length = MCDI_OUT_DWORD(req,
+ GET_PARSER_DISP_INFO_OUT_NUM_SUPPORTED_MATCHES);
+
+ if (req.emr_out_length_used <
+ MC_CMD_GET_PARSER_DISP_INFO_OUT_LEN(*length)) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ memcpy(list,
+ MCDI_OUT2(req,
+ uint32_t,
+ GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES),
+ (*length) * sizeof (uint32_t));
+ EFX_STATIC_ASSERT(sizeof (uint32_t) ==
+ MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_LEN);
+
+ /*
+ * Remove UNKNOWN UCAST and MCAST flags, and if both are present, change
+ * the lower priority one to LOC_MAC_IG.
+ */
+ for (i = 0; i < *length; i++) {
+ if (list[i] & MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN) {
+ list[i] &=
+ (~MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN);
+ support_unknown_ucast = B_TRUE;
+ }
+ if (list[i] & MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN) {
+ list[i] &=
+ (~MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN);
+ support_unknown_mcast = B_TRUE;
+ }
+
+ if (support_unknown_ucast && support_unknown_mcast) {
+ list[i] &= EFX_FILTER_MATCH_LOC_MAC_IG;
+ break;
+ }
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_get_parser_disp_info(enp, list, length) != 0))
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+hunt_filter_unicast_refresh(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *addr,
+ __in boolean_t all_unicst,
+ __in efx_filter_flag_t filter_flags)
+{
+ hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t spec;
+ int rc;
+
+ if (all_unicst == B_TRUE)
+ goto use_uc_def;
+
+ /* Insert the filter for the local station address */
+ efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+ efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC, addr);
+
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_unicst_filter_index);
+ if (rc != 0) {
+ /*
+ * Fall back to an unknown filter. We may be able to subscribe
+ * to it even if we couldn't insert the unicast filter.
+ */
+ goto use_uc_def;
+ }
+ hftp->hft_unicst_filter_set = B_TRUE;
+
+ return (0);
+
+use_uc_def:
+ /* Insert the unknown unicast filter */
+ efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+ efx_filter_spec_set_uc_def(&spec);
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_unicst_filter_index);
+ if (rc != 0)
+ goto fail1;
+
+ hftp->hft_unicst_filter_set = B_TRUE;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ if (hftp->hft_unicst_filter_set != B_FALSE) {
+ (void) hunt_filter_delete_internal(enp,
+ hftp->hft_unicst_filter_index);
+
+ hftp->hft_unicst_filter_set = B_FALSE;
+ }
+
+ return (rc);
+}
+
+static __checkReturn int
+hunt_filter_multicast_refresh(
+ __in efx_nic_t *enp,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count,
+ __in efx_filter_flag_t filter_flags)
+{
+ hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t spec;
+ uint8_t addr[6];
+ unsigned i;
+ int rc;
+
+ if (all_mulcst == B_TRUE)
+ goto use_mc_def;
+
+ if (mulcst == B_FALSE)
+ count = 0;
+
+ if (count + (brdcst ? 1 : 0) >
+ EFX_ARRAY_SIZE(hftp->hft_mulcst_filter_indexes)) {
+ /* Too many MAC addresses; use unknown multicast filter */
+ goto use_mc_def;
+ }
+
+ /* Insert/renew multicast address list filters */
+ hftp->hft_mulcst_filter_count = count;
+ for (i = 0; i < hftp->hft_mulcst_filter_count; i++) {
+ efx_filter_spec_init_rx(&spec,
+ EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+
+ efx_filter_spec_set_eth_local(&spec,
+ EFX_FILTER_SPEC_VID_UNSPEC,
+ &addrs[i * EFX_MAC_ADDR_LEN]);
+
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_mulcst_filter_indexes[i]);
+ if (rc != 0) {
+ /* Rollback, then use unknown multicast filter */
+ goto rollback;
+ }
+ }
+
+ if (brdcst == B_TRUE) {
+ /* Insert/renew broadcast address filter */
+ hftp->hft_mulcst_filter_count++;
+ efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+
+ EFX_MAC_BROADCAST_ADDR_SET(addr);
+ efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
+ addr);
+
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_mulcst_filter_indexes[
+ hftp->hft_mulcst_filter_count - 1]);
+ if (rc != 0) {
+ /* Rollback, then use unknown multicast filter */
+ goto rollback;
+ }
+ }
+
+ return (0);
+
+rollback:
+ /*
+ * Rollback by removing any filters we have inserted
+ * before inserting the unknown multicast filter.
+ */
+ while (i--) {
+ (void) hunt_filter_delete_internal(enp,
+ hftp->hft_mulcst_filter_indexes[i]);
+ }
+ hftp->hft_mulcst_filter_count = 0;
+
+use_mc_def:
+ /* Insert the unknown multicast filter */
+ efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+ efx_filter_spec_set_mc_def(&spec);
+
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_mulcst_filter_indexes[0]);
+ if (rc != 0)
+ goto fail1;
+
+ hftp->hft_mulcst_filter_count = 1;
+
+ /*
+ * FIXME: If brdcst == B_FALSE, add a filter to drop broadcast traffic.
+ */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
+
+
+static __checkReturn int
+hunt_filter_get_workarounds(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+ uint32_t implemented = 0;
+ uint32_t enabled = 0;
+ int rc;
+
+ rc = efx_mcdi_get_workarounds(enp, &implemented, &enabled);
+ if (rc == 0) {
+ /* Check if chained multicast filter support is enabled */
+ if (implemented & enabled & MC_CMD_GET_WORKAROUNDS_OUT_BUG26807)
+ encp->enc_bug26807_workaround = B_TRUE;
+ else
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else if (rc == ENOTSUP) {
+ /*
+ * Firmware is too old to support GET_WORKAROUNDS, and support
+ * for this workaround was implemented later.
+ */
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else {
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
+
+
+/*
+ * Reconfigure all filters.
+ * If all_unicst and/or all mulcst filters cannot be applied then
+ * return ENOTSUP (Note the filters for the specified addresses are
+ * still applied in this case).
+ */
+ __checkReturn int
+hunt_filter_reconfigure(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *mac_addr,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count)
+{
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_flag_t filter_flags;
+ unsigned i;
+ int all_unicst_rc;
+ int all_mulcst_rc;
+ int rc;
+
+ if (table->hft_default_rxq == NULL) {
+ /*
+ * Filters direct traffic to the default RXQ, and so cannot be
+ * inserted until it is available. Any currently configured
+ * filters must be removed (ignore errors in case the MC
+ * has rebooted, which removes hardware filters).
+ */
+ if (table->hft_unicst_filter_set != B_FALSE) {
+ (void) hunt_filter_delete_internal(enp,
+ table->hft_unicst_filter_index);
+ table->hft_unicst_filter_set = B_FALSE;
+ }
+ for (i = 0; i < table->hft_mulcst_filter_count; i++) {
+ (void) hunt_filter_delete_internal(enp,
+ table->hft_mulcst_filter_indexes[i]);
+ }
+ table->hft_mulcst_filter_count = 0;
+
+ return (0);
+ }
+
+ if (table->hft_using_rss)
+ filter_flags = EFX_FILTER_FLAG_RX_RSS;
+ else
+ filter_flags = 0;
+
+ /* Mark old filters which may need to be removed */
+ if (table->hft_unicst_filter_set != B_FALSE) {
+ hunt_filter_set_entry_auto_old(table,
+ table->hft_unicst_filter_index);
+ }
+ for (i = 0; i < table->hft_mulcst_filter_count; i++) {
+ hunt_filter_set_entry_auto_old(table,
+ table->hft_mulcst_filter_indexes[i]);
+ }
+
+ /* Insert or renew unicast filters */
+ if ((all_unicst_rc = hunt_filter_unicast_refresh(enp, mac_addr,
+ all_unicst, filter_flags)) != 0) {
+ if (all_unicst == B_FALSE) {
+ rc = all_unicst_rc;
+ goto fail1;
+ }
+ /* Retry without all_unicast flag */
+ rc = hunt_filter_unicast_refresh(enp, mac_addr,
+ B_FALSE, filter_flags);
+ if (rc != 0)
+ goto fail2;
+ }
+
+ /*
+ * WORKAROUND_BUG26807 controls firmware support for chained multicast
+ * filters, and can only be enabled or disabled when the hardware filter
+ * table is empty.
+ *
+ * Firmware will reset (FLR) functions which have inserted filters in
+ * the hardware filter table when the workaround is enabled/disabled.
+ * Functions without any hardware filters are not reset.
+ *
+ * Re-check if the workaround is enabled after adding unicast hardware
+ * filters. This ensures that encp->enc_workaround_bug26807 matches the
+ * firmware state, and that later changes to enable/disable the
+ * workaround will result in this function seeing a reset (FLR).
+ */
+ if ((rc = hunt_filter_get_workarounds(enp)) != 0)
+ goto fail3;
+
+ /* Insert or renew multicast filters */
+ if ((all_mulcst_rc = hunt_filter_multicast_refresh(enp, mulcst,
+ all_mulcst, brdcst,
+ addrs, count, filter_flags)) != 0) {
+ if (all_mulcst == B_FALSE) {
+ rc = all_mulcst_rc;
+ goto fail4;
+ }
+ /* Retry without all_mulcast flag */
+ rc = hunt_filter_multicast_refresh(enp, mulcst,
+ B_FALSE, brdcst,
+ addrs, count, filter_flags);
+ if (rc != 0)
+ goto fail5;
+ }
+
+ /* Remove old filters which were not renewed */
+ for (i = 0; i < EFX_ARRAY_SIZE(table->hft_entry); i++) {
+ if (hunt_filter_entry_is_auto_old(table, i)) {
+ (void) hunt_filter_delete_internal(enp, i);
+ }
+ }
+
+ /* report if any optional flags were rejected */
+ if (((all_unicst != B_FALSE) && (all_unicst_rc != 0)) ||
+ ((all_mulcst != B_FALSE) && (all_mulcst_rc != 0))) {
+ rc = ENOTSUP;
+ }
+
+ return (rc);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ /* Clear auto old flags */
+ for (i = 0; i < EFX_ARRAY_SIZE(table->hft_entry); i++) {
+ if (hunt_filter_entry_is_auto_old(table, i)) {
+ hunt_filter_set_entry_not_auto_old(table, i);
+ }
+ }
+
+ return (rc);
+}
+
+ void
+hunt_filter_get_default_rxq(
+ __in efx_nic_t *enp,
+ __out efx_rxq_t **erpp,
+ __out boolean_t *using_rss)
+{
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+
+ *erpp = table->hft_default_rxq;
+ *using_rss = table->hft_using_rss;
+}
+
+
+ void
+hunt_filter_default_rxq_set(
+ __in efx_nic_t *enp,
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss)
+{
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+
+#if EFSYS_OPT_RX_SCALE
+ EFSYS_ASSERT((using_rss == B_FALSE) ||
+ (enp->en_rss_context != HUNTINGTON_RSS_CONTEXT_INVALID));
+ table->hft_using_rss = using_rss;
+#else
+ EFSYS_ASSERT(using_rss == B_FALSE);
+ table->hft_using_rss = B_FALSE;
+#endif
+ table->hft_default_rxq = erp;
+}
+
+ void
+hunt_filter_default_rxq_clear(
+ __in efx_nic_t *enp)
+{
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+
+ table->hft_default_rxq = NULL;
+ table->hft_using_rss = B_FALSE;
+}
+
+
+#endif /* EFSYS_OPT_FILTER */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_impl.h b/sys/dev/sfxge/common/hunt_impl.h
new file mode 100644
index 000000000000..d1a4c9401124
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_impl.h
@@ -0,0 +1,1015 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_HUNT_IMPL_H
+#define _SYS_HUNT_IMPL_H
+
+#include "efx.h"
+#include "efx_regs.h"
+#include "efx_regs_ef10.h"
+#include "efx_mcdi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HUNTINGTON_NVRAM_CHUNK 0x80
+
+/* Alignment requirement for value written to RX WPTR:
+ * the WPTR must be aligned to an 8 descriptor boundary
+ */
+#define HUNTINGTON_RX_WPTR_ALIGN 8
+
+/* Invalid RSS context handle */
+#define HUNTINGTON_RSS_CONTEXT_INVALID (0xffffffff)
+
+
+/* EV */
+
+ __checkReturn int
+hunt_ev_init(
+ __in efx_nic_t *enp);
+
+ void
+hunt_ev_fini(
+ __in efx_nic_t *enp);
+
+ __checkReturn int
+hunt_ev_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in efx_evq_t *eep);
+
+ void
+hunt_ev_qdestroy(
+ __in efx_evq_t *eep);
+
+ __checkReturn int
+hunt_ev_qprime(
+ __in efx_evq_t *eep,
+ __in unsigned int count);
+
+ void
+hunt_ev_qpost(
+ __in efx_evq_t *eep,
+ __in uint16_t data);
+
+ __checkReturn int
+hunt_ev_qmoderate(
+ __in efx_evq_t *eep,
+ __in unsigned int us);
+
+#if EFSYS_OPT_QSTATS
+ void
+hunt_ev_qstats_update(
+ __in efx_evq_t *eep,
+ __inout_ecount(EV_NQSTATS) efsys_stat_t *stat);
+#endif /* EFSYS_OPT_QSTATS */
+
+ void
+hunt_ev_rxlabel_init(
+ __in efx_evq_t *eep,
+ __in efx_rxq_t *erp,
+ __in unsigned int label);
+
+ void
+hunt_ev_rxlabel_fini(
+ __in efx_evq_t *eep,
+ __in unsigned int label);
+
+/* INTR */
+
+ __checkReturn int
+hunt_intr_init(
+ __in efx_nic_t *enp,
+ __in efx_intr_type_t type,
+ __in efsys_mem_t *esmp);
+
+ void
+hunt_intr_enable(
+ __in efx_nic_t *enp);
+
+ void
+hunt_intr_disable(
+ __in efx_nic_t *enp);
+
+ void
+hunt_intr_disable_unlocked(
+ __in efx_nic_t *enp);
+
+ __checkReturn int
+hunt_intr_trigger(
+ __in efx_nic_t *enp,
+ __in unsigned int level);
+
+ void
+hunt_intr_fini(
+ __in efx_nic_t *enp);
+
+/* NIC */
+
+extern __checkReturn int
+hunt_nic_probe(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_nic_set_drv_limits(
+ __inout efx_nic_t *enp,
+ __in efx_drv_limits_t *edlp);
+
+extern __checkReturn int
+hunt_nic_get_vi_pool(
+ __in efx_nic_t *enp,
+ __out uint32_t *vi_countp);
+
+extern __checkReturn int
+hunt_nic_get_bar_region(
+ __in efx_nic_t *enp,
+ __in efx_nic_region_t region,
+ __out uint32_t *offsetp,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nic_reset(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_nic_init(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_DIAG
+
+extern __checkReturn int
+hunt_nic_register_test(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_DIAG */
+
+extern void
+hunt_nic_fini(
+ __in efx_nic_t *enp);
+
+extern void
+hunt_nic_unprobe(
+ __in efx_nic_t *enp);
+
+
+/* MAC */
+
+extern __checkReturn int
+hunt_mac_poll(
+ __in efx_nic_t *enp,
+ __out efx_link_mode_t *link_modep);
+
+extern __checkReturn int
+hunt_mac_up(
+ __in efx_nic_t *enp,
+ __out boolean_t *mac_upp);
+
+extern __checkReturn int
+hunt_mac_addr_set(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_mac_reconfigure(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_mac_multicast_list_set(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_mac_filter_default_rxq_set(
+ __in efx_nic_t *enp,
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss);
+
+extern void
+hunt_mac_filter_default_rxq_clear(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_LOOPBACK
+
+extern __checkReturn int
+hunt_mac_loopback_set(
+ __in efx_nic_t *enp,
+ __in efx_link_mode_t link_mode,
+ __in efx_loopback_type_t loopback_type);
+
+#endif /* EFSYS_OPT_LOOPBACK */
+
+#if EFSYS_OPT_MAC_STATS
+
+extern __checkReturn int
+hunt_mac_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
+ __out_opt uint32_t *generationp);
+
+#endif /* EFSYS_OPT_MAC_STATS */
+
+
+/* MCDI */
+
+#if EFSYS_OPT_MCDI
+
+extern __checkReturn int
+hunt_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *mtp);
+
+extern void
+hunt_mcdi_fini(
+ __in efx_nic_t *enp);
+
+extern void
+hunt_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch);
+
+extern __checkReturn boolean_t
+hunt_mcdi_request_poll(
+ __in efx_nic_t *enp);
+
+extern void
+hunt_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp);
+
+extern int
+hunt_mcdi_poll_reboot(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_mcdi_fw_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+extern __checkReturn int
+hunt_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+#endif /* EFSYS_OPT_MCDI */
+
+/* NVRAM */
+
+#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
+
+extern __checkReturn int
+hunt_nvram_buf_read_tlv(
+ __in efx_nic_t *enp,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size,
+ __in uint32_t tag,
+ __deref_out_bcount_opt(*sizep) caddr_t *datap,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nvram_buf_write_tlv(
+ __inout_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size,
+ __in uint32_t tag,
+ __in_bcount(tag_size) caddr_t tag_data,
+ __in size_t tag_size,
+ __out size_t *total_lengthp);
+
+extern __checkReturn int
+hunt_nvram_partn_read_tlv(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t tag,
+ __deref_out_bcount_opt(*sizep) caddr_t *datap,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nvram_partn_write_tlv(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t tag,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_nvram_partn_size(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nvram_partn_lock(
+ __in efx_nic_t *enp,
+ __in unsigned int partn);
+
+extern __checkReturn int
+hunt_nvram_partn_read(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_nvram_partn_erase(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_nvram_partn_write(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern void
+hunt_nvram_partn_unlock(
+ __in efx_nic_t *enp,
+ __in unsigned int partn);
+
+#endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */
+
+#if EFSYS_OPT_NVRAM
+
+#if EFSYS_OPT_DIAG
+
+extern __checkReturn int
+hunt_nvram_test(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_DIAG */
+
+extern __checkReturn int
+hunt_nvram_size(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nvram_get_version(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4]);
+
+extern __checkReturn int
+hunt_nvram_rw_start(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out size_t *pref_chunkp);
+
+extern __checkReturn int
+hunt_nvram_read_chunk(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_nvram_erase(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type);
+
+extern __checkReturn int
+hunt_nvram_write_chunk(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in unsigned int offset,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern void
+hunt_nvram_rw_finish(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type);
+
+extern __checkReturn int
+hunt_nvram_partn_set_version(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in_ecount(4) uint16_t version[4]);
+
+extern __checkReturn int
+hunt_nvram_set_version(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in_ecount(4) uint16_t version[4]);
+
+#endif /* EFSYS_OPT_NVRAM */
+
+
+/* PHY */
+
+typedef struct hunt_link_state_s {
+ uint32_t hls_adv_cap_mask;
+ uint32_t hls_lp_cap_mask;
+ unsigned int hls_fcntl;
+ efx_link_mode_t hls_link_mode;
+#if EFSYS_OPT_LOOPBACK
+ efx_loopback_type_t hls_loopback;
+#endif
+ boolean_t hls_mac_up;
+} hunt_link_state_t;
+
+extern void
+hunt_phy_link_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_link_mode_t *link_modep);
+
+extern __checkReturn int
+hunt_phy_get_link(
+ __in efx_nic_t *enp,
+ __out hunt_link_state_t *hlsp);
+
+extern __checkReturn int
+hunt_phy_power(
+ __in efx_nic_t *enp,
+ __in boolean_t on);
+
+extern __checkReturn int
+hunt_phy_reconfigure(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_phy_verify(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_phy_oui_get(
+ __in efx_nic_t *enp,
+ __out uint32_t *ouip);
+
+#if EFSYS_OPT_PHY_STATS
+
+extern __checkReturn int
+hunt_phy_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_PHY_NSTATS) uint32_t *stat);
+
+#endif /* EFSYS_OPT_PHY_STATS */
+
+#if EFSYS_OPT_PHY_PROPS
+
+#if EFSYS_OPT_NAMES
+
+extern const char *
+hunt_phy_prop_name(
+ __in efx_nic_t *enp,
+ __in unsigned int id);
+
+#endif /* EFSYS_OPT_NAMES */
+
+extern __checkReturn int
+hunt_phy_prop_get(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t flags,
+ __out uint32_t *valp);
+
+extern __checkReturn int
+hunt_phy_prop_set(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t val);
+
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+#if EFSYS_OPT_BIST
+
+extern __checkReturn int
+hunt_bist_enable_offline(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_bist_start(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type);
+
+extern __checkReturn int
+hunt_bist_poll(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
+ __out_opt __drv_when(count > 0, __notnull)
+ uint32_t *value_maskp,
+ __out_ecount_opt(count) __drv_when(count > 0, __notnull)
+ unsigned long *valuesp,
+ __in size_t count);
+
+extern void
+hunt_bist_stop(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type);
+
+#endif /* EFSYS_OPT_BIST */
+
+
+/* SRAM */
+
+#if EFSYS_OPT_DIAG
+
+extern __checkReturn int
+hunt_sram_test(
+ __in efx_nic_t *enp,
+ __in efx_sram_pattern_fn_t func);
+
+#endif /* EFSYS_OPT_DIAG */
+
+
+/* TX */
+
+extern __checkReturn int
+hunt_tx_init(
+ __in efx_nic_t *enp);
+
+extern void
+hunt_tx_fini(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_tx_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in unsigned int label,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in uint16_t flags,
+ __in efx_evq_t *eep,
+ __in efx_txq_t *etp,
+ __out unsigned int *addedp);
+
+extern void
+hunt_tx_qdestroy(
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+hunt_tx_qpost(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_buffer_t *eb,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+extern void
+hunt_tx_qpush(
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed);
+
+extern __checkReturn int
+hunt_tx_qpace(
+ __in efx_txq_t *etp,
+ __in unsigned int ns);
+
+extern __checkReturn int
+hunt_tx_qflush(
+ __in efx_txq_t *etp);
+
+extern void
+hunt_tx_qenable(
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+hunt_tx_qpio_enable(
+ __in efx_txq_t *etp);
+
+extern void
+hunt_tx_qpio_disable(
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+hunt_tx_qpio_write(
+ __in efx_txq_t *etp,
+ __in_ecount(buf_length) uint8_t *buffer,
+ __in size_t buf_length,
+ __in size_t pio_buf_offset);
+
+extern __checkReturn int
+hunt_tx_qpio_post(
+ __in efx_txq_t *etp,
+ __in size_t pkt_length,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+extern __checkReturn int
+hunt_tx_qdesc_post(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_desc_t *ed,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+extern void
+hunt_tx_qdesc_dma_create(
+ __in efx_txq_t *etp,
+ __in efsys_dma_addr_t addr,
+ __in size_t size,
+ __in boolean_t eop,
+ __out efx_desc_t *edp);
+
+extern void
+hunt_tx_qdesc_tso_create(
+ __in efx_txq_t *etp,
+ __in uint16_t ipv4_id,
+ __in uint32_t tcp_seq,
+ __in uint8_t tcp_flags,
+ __out efx_desc_t *edp);
+
+extern void
+hunt_tx_qdesc_vlantci_create(
+ __in efx_txq_t *etp,
+ __in uint16_t vlan_tci,
+ __out efx_desc_t *edp);
+
+
+#if EFSYS_OPT_QSTATS
+
+extern void
+hunt_tx_qstats_update(
+ __in efx_txq_t *etp,
+ __inout_ecount(TX_NQSTATS) efsys_stat_t *stat);
+
+#endif /* EFSYS_OPT_QSTATS */
+
+/* PIO */
+
+/* Missing register definitions */
+#ifndef ER_DZ_TX_PIOBUF_OFST
+#define ER_DZ_TX_PIOBUF_OFST 0x00001000
+#endif
+#ifndef ER_DZ_TX_PIOBUF_STEP
+#define ER_DZ_TX_PIOBUF_STEP 8192
+#endif
+#ifndef ER_DZ_TX_PIOBUF_ROWS
+#define ER_DZ_TX_PIOBUF_ROWS 2048
+#endif
+
+#ifndef ER_DZ_TX_PIOBUF_SIZE
+#define ER_DZ_TX_PIOBUF_SIZE 2048
+#endif
+
+#define HUNT_PIOBUF_NBUFS (16)
+#define HUNT_PIOBUF_SIZE (ER_DZ_TX_PIOBUF_SIZE)
+
+#define HUNT_MIN_PIO_ALLOC_SIZE (HUNT_PIOBUF_SIZE / 32)
+
+typedef uint32_t efx_piobuf_handle_t;
+
+#define EFX_PIOBUF_HANDLE_INVALID ((efx_piobuf_handle_t) -1)
+
+extern __checkReturn int
+hunt_nic_pio_alloc(
+ __inout efx_nic_t *enp,
+ __out uint32_t *bufnump,
+ __out efx_piobuf_handle_t *handlep,
+ __out uint32_t *blknump,
+ __out uint32_t *offsetp,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nic_pio_free(
+ __inout efx_nic_t *enp,
+ __in uint32_t bufnum,
+ __in uint32_t blknum);
+
+extern __checkReturn int
+hunt_nic_pio_link(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index,
+ __in efx_piobuf_handle_t handle);
+
+extern __checkReturn int
+hunt_nic_pio_unlink(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index);
+
+
+/* VPD */
+
+#if EFSYS_OPT_VPD
+
+extern __checkReturn int
+hunt_vpd_init(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_vpd_size(
+ __in efx_nic_t *enp,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_vpd_read(
+ __in efx_nic_t *enp,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_vpd_verify(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_vpd_reinit(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_vpd_get(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __inout efx_vpd_value_t *evvp);
+
+extern __checkReturn int
+hunt_vpd_set(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __in efx_vpd_value_t *evvp);
+
+extern __checkReturn int
+hunt_vpd_next(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __out efx_vpd_value_t *evvp,
+ __inout unsigned int *contp);
+
+extern __checkReturn int
+hunt_vpd_write(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern void
+hunt_vpd_fini(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_VPD */
+
+
+/* RX */
+
+extern __checkReturn int
+hunt_rx_init(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_RX_HDR_SPLIT
+extern __checkReturn int
+hunt_rx_hdr_split_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int hdr_buf_size,
+ __in unsigned int pld_buf_size);
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+#if EFSYS_OPT_RX_SCATTER
+extern __checkReturn int
+hunt_rx_scatter_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int buf_size);
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+
+#if EFSYS_OPT_RX_SCALE
+
+extern __checkReturn int
+hunt_rx_scale_mode_set(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t alg,
+ __in efx_rx_hash_type_t type,
+ __in boolean_t insert);
+
+extern __checkReturn int
+hunt_rx_scale_key_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n);
+
+extern __checkReturn int
+hunt_rx_scale_tbl_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n);
+
+#endif /* EFSYS_OPT_RX_SCALE */
+
+extern void
+hunt_rx_qpost(
+ __in efx_rxq_t *erp,
+ __in_ecount(n) efsys_dma_addr_t *addrp,
+ __in size_t size,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __in unsigned int added);
+
+extern void
+hunt_rx_qpush(
+ __in efx_rxq_t *erp,
+ __in unsigned int added,
+ __inout unsigned int *pushedp);
+
+extern __checkReturn int
+hunt_rx_qflush(
+ __in efx_rxq_t *erp);
+
+extern void
+hunt_rx_qenable(
+ __in efx_rxq_t *erp);
+
+extern __checkReturn int
+hunt_rx_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in unsigned int label,
+ __in efx_rxq_type_t type,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in efx_evq_t *eep,
+ __in efx_rxq_t *erp);
+
+extern void
+hunt_rx_qdestroy(
+ __in efx_rxq_t *erp);
+
+extern void
+hunt_rx_fini(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_FILTER
+
+typedef struct hunt_filter_handle_s {
+ uint32_t hfh_lo;
+ uint32_t hfh_hi;
+} hunt_filter_handle_t;
+
+typedef struct hunt_filter_entry_s {
+ uintptr_t hfe_spec; /* pointer to filter spec plus busy bit */
+ hunt_filter_handle_t hfe_handle;
+} hunt_filter_entry_t;
+
+/*
+ * BUSY flag indicates that an update is in progress.
+ * AUTO_OLD flag is used to mark and sweep MAC packet filters.
+ */
+#define EFX_HUNT_FILTER_FLAG_BUSY 1U
+#define EFX_HUNT_FILTER_FLAG_AUTO_OLD 2U
+#define EFX_HUNT_FILTER_FLAGS 3U
+
+#define EFX_HUNT_FILTER_TBL_ROWS 8192
+
+/* Allow for the broadcast address to be added to the multicast list */
+#define EFX_HUNT_FILTER_MULTICAST_FILTERS_MAX (EFX_MAC_MULTICAST_LIST_MAX + 1)
+
+typedef struct hunt_filter_table_s {
+ hunt_filter_entry_t hft_entry[EFX_HUNT_FILTER_TBL_ROWS];
+ efx_rxq_t * hft_default_rxq;
+ boolean_t hft_using_rss;
+ uint32_t hft_unicst_filter_index;
+ boolean_t hft_unicst_filter_set;
+ uint32_t hft_mulcst_filter_indexes[
+ EFX_HUNT_FILTER_MULTICAST_FILTERS_MAX];
+ uint32_t hft_mulcst_filter_count;
+} hunt_filter_table_t;
+
+ __checkReturn int
+hunt_filter_init(
+ __in efx_nic_t *enp);
+
+ void
+hunt_filter_fini(
+ __in efx_nic_t *enp);
+
+ __checkReturn int
+hunt_filter_restore(
+ __in efx_nic_t *enp);
+
+ __checkReturn int
+hunt_filter_add(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec,
+ __in boolean_t may_replace);
+
+ __checkReturn int
+hunt_filter_delete(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec);
+
+extern __checkReturn int
+hunt_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length);
+
+extern __checkReturn int
+hunt_filter_reconfigure(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *mac_addr,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count);
+
+extern void
+hunt_filter_get_default_rxq(
+ __in efx_nic_t *enp,
+ __out efx_rxq_t **erpp,
+ __out boolean_t *using_rss);
+
+extern void
+hunt_filter_default_rxq_set(
+ __in efx_nic_t *enp,
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss);
+
+extern void
+hunt_filter_default_rxq_clear(
+ __in efx_nic_t *enp);
+
+
+#endif /* EFSYS_OPT_FILTER */
+
+extern __checkReturn int
+hunt_pktfilter_set(
+ __in efx_nic_t *enp,
+ __in boolean_t unicst,
+ __in boolean_t brdcst);
+
+#if EFSYS_OPT_MCAST_FILTER_LIST
+
+extern __checkReturn int
+hunt_pktfilter_mcast_set(
+ __in efx_nic_t *enp,
+ __in uint8_t const *addrs,
+ __in int count);
+
+#endif /* EFSYS_OPT_MCAST_FILTER_LIST */
+
+extern __checkReturn int
+hunt_pktfilter_mcast_all(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_get_function_info(
+ __in efx_nic_t *enp,
+ __out uint32_t *pfp,
+ __out_opt uint32_t *vfp);
+
+extern __checkReturn int
+efx_mcdi_privilege_mask(
+ __in efx_nic_t *enp,
+ __in uint32_t pf,
+ __in uint32_t vf,
+ __out uint32_t *maskp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_HUNT_IMPL_H */
diff --git a/sys/dev/sfxge/common/hunt_intr.c b/sys/dev/sfxge/common/hunt_intr.c
new file mode 100644
index 000000000000..b68135cfd947
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_intr.c
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+ __checkReturn int
+hunt_intr_init(
+ __in efx_nic_t *enp,
+ __in efx_intr_type_t type,
+ __in efsys_mem_t *esmp)
+{
+ _NOTE(ARGUNUSED(enp, type, esmp))
+ return (0);
+}
+
+
+ void
+hunt_intr_enable(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+
+ void
+hunt_intr_disable(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+
+ void
+hunt_intr_disable_unlocked(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+
+static __checkReturn int
+efx_mcdi_trigger_interrupt(
+ __in efx_nic_t *enp,
+ __in unsigned int level)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_TRIGGER_INTERRUPT_IN_LEN,
+ MC_CMD_TRIGGER_INTERRUPT_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ if (level >= enp->en_nic_cfg.enc_intr_limit) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_TRIGGER_INTERRUPT_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, TRIGGER_INTERRUPT_IN_INTR_LEVEL, level);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_intr_trigger(
+ __in efx_nic_t *enp,
+ __in unsigned int level)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ int rc;
+
+ if (encp->enc_bug41750_workaround) {
+ /* bug 41750: Test interrupts don't work on Greenport */
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = efx_mcdi_trigger_interrupt(enp, level)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ void
+hunt_intr_fini(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_mac.c b/sys/dev/sfxge/common/hunt_mac.c
new file mode 100644
index 000000000000..b9f7ca4a2073
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_mac.c
@@ -0,0 +1,685 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+ __checkReturn int
+hunt_mac_poll(
+ __in efx_nic_t *enp,
+ __out efx_link_mode_t *link_modep)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+
+ efx_port_t *epp = &(enp->en_port);
+ hunt_link_state_t hls;
+ int rc;
+
+ if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ goto fail1;
+
+ epp->ep_adv_cap_mask = hls.hls_adv_cap_mask;
+ epp->ep_fcntl = hls.hls_fcntl;
+
+ *link_modep = hls.hls_link_mode;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ *link_modep = EFX_LINK_UNKNOWN;
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mac_up(
+ __in efx_nic_t *enp,
+ __out boolean_t *mac_upp)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+
+ hunt_link_state_t hls;
+ int rc;
+
+ /*
+ * Because Huntington doesn't *require* polling, we can't rely on
+ * hunt_mac_poll() being executed to populate epp->ep_mac_up.
+ */
+ if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ goto fail1;
+
+ *mac_upp = hls.hls_mac_up;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * Huntington uses MC_CMD_VADAPTOR_SET_MAC to set the
+ * MAC address; the address field in MC_CMD_SET_MAC has no
+ * effect.
+ * MC_CMD_VADAPTOR_SET_MAC requires mac-spoofing privilege and
+ * the port to have no filters or queues active.
+ */
+static __checkReturn int
+efx_mcdi_vadapter_set_mac(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VADAPTOR_SET_MAC_IN_LEN,
+ MC_CMD_VADAPTOR_SET_MAC_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VADAPTOR_SET_MAC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID,
+ enp->en_vport_id);
+ EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, VADAPTOR_SET_MAC_IN_MACADDR),
+ epp->ep_mac_addr);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mac_addr_set(
+ __in efx_nic_t *enp)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_vadapter_set_mac(enp)) != 0)
+ goto fail1;
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+__checkReturn int
+hunt_mac_reconfigure(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
+ MC_CMD_SET_MAC_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SET_MAC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
+ MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
+ EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
+ epp->ep_mac_addr);
+
+ /*
+ * Note: The Huntington MAC does not support REJECT_BRDCST.
+ * The REJECT_UNCST flag will also prevent multicast traffic
+ * from reaching the filters. As Huntington filters drop any
+ * traffic that does not match a filter it is ok to leave the
+ * MAC running in promiscuous mode. See bug41141.
+ */
+ MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
+ SET_MAC_IN_REJECT_UNCST, 0,
+ SET_MAC_IN_REJECT_BRDCST, 0);
+
+ /*
+ * Flow control, whether it is auto-negotiated or not,
+ * is set via the PHY advertised capabilities. When set to
+ * automatic the MAC will use the PHY settings to determine
+ * the flow control settings.
+ */
+ MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, MC_CMD_FCNTL_AUTO);
+
+ /* Do not include the Ethernet frame checksum in RX packets */
+ MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_IN_FLAGS,
+ SET_MAC_IN_FLAG_INCLUDE_FCS, 0);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ /*
+ * Unprivileged functions cannot control link state,
+ * but still need to configure filters.
+ */
+ if (req.emr_rc != EACCES) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+ }
+
+ /*
+ * Apply the filters for the MAC configuration.
+ * If the NIC isn't ready to accept filters this may
+ * return success without setting anything.
+ */
+ rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
+ epp->ep_all_unicst, epp->ep_mulcst,
+ epp->ep_all_mulcst, epp->ep_brdcst,
+ epp->ep_mulcst_addr_list,
+ epp->ep_mulcst_addr_count);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mac_multicast_list_set(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mac_ops_t *emop = epp->ep_emop;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /* FIXME: Insert filters for multicast list */
+
+ if ((rc = emop->emo_reconfigure(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mac_filter_default_rxq_set(
+ __in efx_nic_t *enp,
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_rxq_t *old_rxq;
+ boolean_t old_using_rss;
+ int rc;
+
+ hunt_filter_get_default_rxq(enp, &old_rxq, &old_using_rss);
+
+ hunt_filter_default_rxq_set(enp, erp, using_rss);
+
+ rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
+ epp->ep_all_unicst, epp->ep_mulcst,
+ epp->ep_all_mulcst, epp->ep_brdcst,
+ epp->ep_mulcst_addr_list,
+ epp->ep_mulcst_addr_count);
+
+ if (rc != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ hunt_filter_default_rxq_set(enp, old_rxq, old_using_rss);
+
+ return (rc);
+}
+
+ void
+hunt_mac_filter_default_rxq_clear(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+
+ hunt_filter_default_rxq_clear(enp);
+
+ efx_filter_reconfigure(enp, epp->ep_mac_addr,
+ epp->ep_all_unicst, epp->ep_mulcst,
+ epp->ep_all_mulcst, epp->ep_brdcst,
+ epp->ep_mulcst_addr_list,
+ epp->ep_mulcst_addr_count);
+}
+
+
+#if EFSYS_OPT_LOOPBACK
+
+ __checkReturn int
+hunt_mac_loopback_set(
+ __in efx_nic_t *enp,
+ __in efx_link_mode_t link_mode,
+ __in efx_loopback_type_t loopback_type)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+
+ efx_port_t *epp = &(enp->en_port);
+ efx_phy_ops_t *epop = epp->ep_epop;
+ efx_loopback_type_t old_loopback_type;
+ efx_link_mode_t old_loopback_link_mode;
+ int rc;
+
+ /* The PHY object handles this on Huntington */
+ old_loopback_type = epp->ep_loopback_type;
+ old_loopback_link_mode = epp->ep_loopback_link_mode;
+ epp->ep_loopback_type = loopback_type;
+ epp->ep_loopback_link_mode = link_mode;
+
+ if ((rc = epop->epo_reconfigure(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE(fail2);
+
+ epp->ep_loopback_type = old_loopback_type;
+ epp->ep_loopback_link_mode = old_loopback_link_mode;
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_LOOPBACK */
+
+#if EFSYS_OPT_MAC_STATS
+
+#define HUNT_MAC_STAT_READ(_esmp, _field, _eqp) \
+ EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
+
+
+ __checkReturn int
+hunt_mac_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
+ __out_opt uint32_t *generationp)
+{
+ efx_qword_t value;
+ efx_qword_t generation_start;
+ efx_qword_t generation_end;
+
+ _NOTE(ARGUNUSED(enp))
+
+ /* Read END first so we don't race with the MC */
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
+ &generation_end);
+ EFSYS_MEM_READ_BARRIER();
+
+ /* TX */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value);
+ EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
+
+ /* RX */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value);
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]),
+ &(value.eq_dword[0]));
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]),
+ &(value.eq_dword[1]));
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value);
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]),
+ &(value.eq_dword[0]));
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]),
+ &(value.eq_dword[1]));
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value);
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]),
+ &(value.eq_dword[0]));
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]),
+ &(value.eq_dword[1]));
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value);
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]),
+ &(value.eq_dword[0]));
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]),
+ &(value.eq_dword[1]));
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
+
+ /* Packet memory (EF10 only) */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_BB_OVERFLOW]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_BB_OVERFLOW]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_VFIFO_FULL, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_VFIFO_FULL]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_VFIFO_FULL, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_VFIFO_FULL]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_QBB, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_QBB]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_QBB, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_QBB]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_MAPPING, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_MAPPING]), &value);
+
+ /* RX datapath */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_Q_DISABLED_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_Q_DISABLED_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_DI_DROPPED_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_DI_DROPPED_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_STREAMING_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_STREAMING_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_FETCH]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_WAIT]), &value);
+
+
+ /* VADAPTER RX */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_BYTES]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_OVERFLOW, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_OVERFLOW]), &value);
+
+ /* VADAPTER TX */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_PACKETS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_BYTES]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_OVERFLOW, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_OVERFLOW]), &value);
+
+
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
+ EFSYS_MEM_READ_BARRIER();
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
+ &generation_start);
+
+ /* Check that we didn't read the stats in the middle of a DMA */
+ /* Not a good enough check ? */
+ if (memcmp(&generation_start, &generation_end,
+ sizeof (generation_start)))
+ return (EAGAIN);
+
+ if (generationp)
+ *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0);
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_MAC_STATS */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_mcdi.c b/sys/dev/sfxge/common/hunt_mcdi.c
new file mode 100644
index 000000000000..8782bcce5a30
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_mcdi.c
@@ -0,0 +1,465 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_MCDI
+
+#ifndef WITH_MCDI_V2
+#error "WITH_MCDI_V2 required for Huntington MCDIv2 commands."
+#endif
+
+typedef enum efx_mcdi_header_type_e {
+ EFX_MCDI_HEADER_TYPE_V1, /* MCDIv0 (BootROM), MCDIv1 commands */
+ EFX_MCDI_HEADER_TYPE_V2, /* MCDIv2 commands */
+} efx_mcdi_header_type_t;
+
+/*
+ * Return the header format to use for sending an MCDI request.
+ *
+ * An MCDIv1 (Siena compatible) command should use MCDIv2 encapsulation if the
+ * request input buffer or response output buffer are too large for the MCDIv1
+ * format. An MCDIv2 command must always be sent using MCDIv2 encapsulation.
+ */
+#define EFX_MCDI_HEADER_TYPE(_cmd, _length) \
+ ((((_cmd) & ~EFX_MASK32(MCDI_HEADER_CODE)) || \
+ ((_length) & ~EFX_MASK32(MCDI_HEADER_DATALEN))) ? \
+ EFX_MCDI_HEADER_TYPE_V2 : EFX_MCDI_HEADER_TYPE_V1)
+
+
+/*
+ * MCDI Header NOT_EPOCH flag
+ * ==========================
+ * A new epoch begins at initial startup or after an MC reboot, and defines when
+ * the MC should reject stale MCDI requests.
+ *
+ * The first MCDI request sent by the host should contain NOT_EPOCH=0, and all
+ * subsequent requests (until the next MC reboot) should contain NOT_EPOCH=1.
+ *
+ * After rebooting the MC will fail all requests with NOT_EPOCH=1 by writing a
+ * response with ERROR=1 and DATALEN=0 until a request is seen with NOT_EPOCH=0.
+ */
+
+
+ __checkReturn int
+hunt_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *emtp)
+{
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ efx_dword_t dword;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+ EFSYS_ASSERT(enp->en_features & EFX_FEATURE_MCDI_DMA);
+
+ /* A host DMA buffer is required for Huntington MCDI */
+ if (esmp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /*
+ * Ensure that the MC doorbell is in a known state before issuing MCDI
+ * commands. The recovery algorithm requires that the MC command buffer
+ * must be 256 byte aligned. See bug24769.
+ */
+ if ((EFSYS_MEM_ADDR(esmp) & 0xFF) != 0) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 1);
+ EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE);
+
+ /* Save initial MC reboot status */
+ (void) hunt_mcdi_poll_reboot(enp);
+
+ /* Start a new epoch (allow fresh MCDI requests to succeed) */
+ efx_mcdi_new_epoch(enp);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_mcdi_fini(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+
+ emip->emi_new_epoch = B_FALSE;
+}
+
+ void
+hunt_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch)
+{
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ efx_mcdi_header_type_t hdr_type;
+ efx_dword_t dword;
+ unsigned int xflags;
+ unsigned int pos;
+ size_t offset;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ xflags = 0;
+ if (ev_cpl)
+ xflags |= MCDI_HEADER_XFLAGS_EVREQ;
+
+ offset = 0;
+
+ hdr_type = EFX_MCDI_HEADER_TYPE(emrp->emr_cmd,
+ MAX(emrp->emr_in_length, emrp->emr_out_length));
+
+ if (hdr_type == EFX_MCDI_HEADER_TYPE_V2) {
+ /* Construct MCDI v2 header */
+ EFX_POPULATE_DWORD_8(dword,
+ MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
+ MCDI_HEADER_RESYNC, 1,
+ MCDI_HEADER_DATALEN, 0,
+ MCDI_HEADER_SEQ, seq,
+ MCDI_HEADER_NOT_EPOCH, new_epoch ? 0 : 1,
+ MCDI_HEADER_ERROR, 0,
+ MCDI_HEADER_RESPONSE, 0,
+ MCDI_HEADER_XFLAGS, xflags);
+ EFSYS_MEM_WRITED(esmp, offset, &dword);
+ offset += sizeof (dword);
+
+ EFX_POPULATE_DWORD_2(dword,
+ MC_CMD_V2_EXTN_IN_EXTENDED_CMD, emrp->emr_cmd,
+ MC_CMD_V2_EXTN_IN_ACTUAL_LEN, emrp->emr_in_length);
+ EFSYS_MEM_WRITED(esmp, offset, &dword);
+ offset += sizeof (dword);
+ } else {
+ /* Construct MCDI v1 header */
+ EFX_POPULATE_DWORD_8(dword,
+ MCDI_HEADER_CODE, emrp->emr_cmd,
+ MCDI_HEADER_RESYNC, 1,
+ MCDI_HEADER_DATALEN, emrp->emr_in_length,
+ MCDI_HEADER_SEQ, seq,
+ MCDI_HEADER_NOT_EPOCH, new_epoch ? 0 : 1,
+ MCDI_HEADER_ERROR, 0,
+ MCDI_HEADER_RESPONSE, 0,
+ MCDI_HEADER_XFLAGS, xflags);
+ EFSYS_MEM_WRITED(esmp, offset, &dword);
+ offset += sizeof (dword);
+ }
+
+ /* Construct the payload */
+ for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
+ memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
+ MIN(sizeof (dword), emrp->emr_in_length - pos));
+ EFSYS_MEM_WRITED(esmp, offset + pos, &dword);
+ }
+
+ /* Ring the doorbell to post the command DMA address to the MC */
+ EFSYS_ASSERT((EFSYS_MEM_ADDR(esmp) & 0xFF) == 0);
+
+ /* Guarantee ordering of memory (MCDI request) and PIO (MC doorbell) */
+ EFSYS_DMA_SYNC_FOR_DEVICE(esmp, 0, offset + emrp->emr_in_length);
+ EFSYS_PIO_WRITE_BARRIER();
+
+ EFX_POPULATE_DWORD_1(dword,
+ EFX_DWORD_0, EFSYS_MEM_ADDR(esmp) >> 32);
+ EFX_BAR_WRITED(enp, ER_DZ_MC_DB_LWRD_REG, &dword, B_FALSE);
+
+ EFX_POPULATE_DWORD_1(dword,
+ EFX_DWORD_0, EFSYS_MEM_ADDR(esmp) & 0xffffffff);
+ EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE);
+}
+
+ void
+hunt_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp)
+{
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ unsigned int pos;
+ unsigned int offset;
+ efx_dword_t hdr;
+ efx_dword_t hdr2;
+ efx_dword_t data;
+ size_t bytes;
+
+ if (emrp->emr_out_buf == NULL)
+ return;
+
+ /* Read the command header to detect MCDI response format */
+ EFSYS_MEM_READD(esmp, 0, &hdr);
+ if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
+ offset = 2 * sizeof (efx_dword_t);
+
+ /*
+ * Read the actual payload length. The length given in the event
+ * is only correct for responses with the V1 format.
+ */
+ EFSYS_MEM_READD(esmp, sizeof (efx_dword_t), &hdr2);
+ emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr2,
+ MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+ } else {
+ offset = sizeof (efx_dword_t);
+ }
+
+ /* Copy payload out into caller supplied buffer */
+ bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
+ for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) {
+ EFSYS_MEM_READD(esmp, offset + pos, &data);
+ memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
+ MIN(sizeof (data), bytes - pos));
+ }
+}
+
+ __checkReturn boolean_t
+hunt_mcdi_request_poll(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ efx_mcdi_req_t *emrp;
+ efx_dword_t dword;
+ unsigned int seq;
+ unsigned int cmd;
+ unsigned int length;
+ size_t offset;
+ int state;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* Serialise against post-watchdog efx_mcdi_ev* */
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ EFSYS_ASSERT(emip->emi_pending_req != NULL);
+ EFSYS_ASSERT(!emip->emi_ev_cpl);
+ emrp = emip->emi_pending_req;
+
+ offset = 0;
+
+ /* Read the command header */
+ EFSYS_MEM_READD(esmp, offset, &dword);
+ offset += sizeof (efx_dword_t);
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (B_FALSE);
+ }
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
+ efx_dword_t dword2;
+
+ EFSYS_MEM_READD(esmp, offset, &dword2);
+ offset += sizeof (efx_dword_t);
+
+ cmd = EFX_DWORD_FIELD(dword2, MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
+ length = EFX_DWORD_FIELD(dword2, MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+ } else {
+ cmd = EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE);
+ length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
+ }
+
+ /* Request complete */
+ emip->emi_pending_req = NULL;
+ seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
+
+ /* Check for synchronous reboot */
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 && length == 0) {
+ /* The MC has rebooted since the request was sent. */
+ EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
+ hunt_mcdi_poll_reboot(enp);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ rc = EIO;
+ goto fail1;
+ }
+
+ /* Ensure stale MCDI requests fail after an MC reboot. */
+ emip->emi_new_epoch = B_FALSE;
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ /* Check that the returned data is consistent */
+ if (cmd != emrp->emr_cmd ||
+ EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
+ /* Response is for a different request */
+ rc = EIO;
+ goto fail2;
+ }
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
+ efx_dword_t errdword;
+ int errcode;
+ int argnum;
+
+ /* Read error code (and arg num for MCDI v2 commands) */
+ EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_CODE_OFST, &errdword);
+ errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
+
+ EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_ARG_OFST, &errdword);
+ argnum = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
+
+ rc = efx_mcdi_request_errcode(errcode);
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd,
+ int, errcode, int, argnum);
+ }
+ goto fail3;
+
+ } else {
+ emrp->emr_out_length_used = length;
+ emrp->emr_rc = 0;
+ hunt_mcdi_request_copyout(enp, emrp);
+ }
+
+ goto out;
+
+fail3:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail3);
+fail2:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail2);
+fail1:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE1(fail1, int, rc);
+
+ /* Fill out error state */
+ emrp->emr_rc = rc;
+ emrp->emr_out_length_used = 0;
+
+ /* Reboot/Assertion */
+ if (rc == EIO || rc == EINTR)
+ efx_mcdi_raise_exception(enp, emrp, rc);
+
+out:
+ return (B_TRUE);
+}
+
+ int
+hunt_mcdi_poll_reboot(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_dword_t dword;
+ uint32_t old_status;
+ uint32_t new_status;
+ int rc;
+
+ old_status = emip->emi_mc_reboot_status;
+
+ /* Update MC reboot status word */
+ EFX_BAR_TBL_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, 0, &dword, B_FALSE);
+ new_status = dword.ed_u32[0];
+
+ /* MC has rebooted if the value has changed */
+ if (new_status != old_status) {
+ emip->emi_mc_reboot_status = new_status;
+
+ /*
+ * FIXME: Ignore detected MC REBOOT for now.
+ *
+ * The Siena support for checking for MC reboot from status
+ * flags is broken - see comments in siena_mcdi_poll_reboot().
+ * As the generic MCDI code is shared the Huntington reboot
+ * detection suffers similar problems.
+ *
+ * Do not report an error when the boot status changes until
+ * this can be handled by common code drivers (and reworked to
+ * support Siena too).
+ */
+ if (B_FALSE) {
+ rc = EIO;
+ goto fail1;
+ }
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mcdi_fw_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* use privilege mask state at MCDI attach */
+ *supportedp = (encp->enc_privilege_mask &
+ MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN)
+ == MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN;
+
+ return (0);
+}
+
+ __checkReturn int
+hunt_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* use privilege mask state at MCDI attach */
+ *supportedp = (encp->enc_privilege_mask &
+ MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING)
+ == MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING;
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_MCDI */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_nic.c b/sys/dev/sfxge/common/hunt_nic.c
new file mode 100644
index 000000000000..a4babc39eab6
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_nic.c
@@ -0,0 +1,1741 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+#include "mcdi_mon.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+#include "ef10_tlv_layout.h"
+
+static __checkReturn int
+efx_mcdi_get_port_assignment(
+ __in efx_nic_t *enp,
+ __out uint32_t *portp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
+ MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_port_modes(
+ __in efx_nic_t *enp,
+ __out uint32_t *modesp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
+ MC_CMD_GET_PORT_MODES_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PORT_MODES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ /* Accept pre-Medford size (8 bytes - no CurrentMode field) */
+ if (req.emr_out_length_used <
+ MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_vadaptor_alloc(
+ __in efx_nic_t *enp,
+ __in uint32_t port_id)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
+ MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_vadaptor_free(
+ __in efx_nic_t *enp,
+ __in uint32_t port_id)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
+ MC_CMD_VADAPTOR_FREE_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VADAPTOR_FREE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_mac_address_pf(
+ __in efx_nic_t *enp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6])
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ if (mac_addrp != NULL) {
+ uint8_t *addrp;
+
+ addrp = MCDI_OUT2(req, uint8_t,
+ GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE);
+
+ EFX_MAC_ADDR_COPY(mac_addrp, addrp);
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_mac_address_vf(
+ __in efx_nic_t *enp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6])
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID,
+ EVB_PORT_ID_ASSIGNED);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used <
+ MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (MCDI_OUT_DWORD(req,
+ VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ if (mac_addrp != NULL) {
+ uint8_t *addrp;
+
+ addrp = MCDI_OUT2(req, uint8_t,
+ VPORT_GET_MAC_ADDRESSES_OUT_MACADDR);
+
+ EFX_MAC_ADDR_COPY(mac_addrp, addrp);
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_clock(
+ __in efx_nic_t *enp,
+ __out uint32_t *sys_freqp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
+ MC_CMD_GET_CLOCK_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_CLOCK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ);
+ if (*sys_freqp == 0) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_vector_cfg(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *vec_basep,
+ __out_opt uint32_t *pf_nvecp,
+ __out_opt uint32_t *vf_nvecp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
+ MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (vec_basep != NULL)
+ *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE);
+ if (pf_nvecp != NULL)
+ *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF);
+ if (vf_nvecp != NULL)
+ *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_capabilities(
+ __in efx_nic_t *enp,
+ __out efx_dword_t *flagsp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
+ MC_CMD_GET_CAPABILITIES_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_CAPABILITIES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_CAPABILITIES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *flagsp = *MCDI_OUT2(req, efx_dword_t, GET_CAPABILITIES_OUT_FLAGS1);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_alloc_vis(
+ __in efx_nic_t *enp,
+ __in uint32_t min_vi_count,
+ __in uint32_t max_vi_count,
+ __out_opt uint32_t *vi_basep,
+ __out uint32_t *vi_countp)
+
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
+ MC_CMD_ALLOC_VIS_OUT_LEN)];
+ int rc;
+
+ if (vi_countp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ALLOC_VIS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ALLOC_VIS_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count);
+ MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ if (vi_basep != NULL)
+ *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE);
+
+ if (vi_countp != NULL)
+ *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_free_vis(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ int rc;
+
+ EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0);
+ EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0);
+
+ req.emr_cmd = MC_CMD_FREE_VIS;
+ req.emr_in_buf = NULL;
+ req.emr_in_length = 0;
+ req.emr_out_buf = NULL;
+ req.emr_out_length = 0;
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ /* Ignore ELREADY (no allocated VIs, so nothing to free) */
+ if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_alloc_piobuf(
+ __in efx_nic_t *enp,
+ __out efx_piobuf_handle_t *handlep)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
+ MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
+ int rc;
+
+ if (handlep == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN;
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_free_piobuf(
+ __in efx_nic_t *enp,
+ __out efx_piobuf_handle_t handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
+ MC_CMD_FREE_PIOBUF_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FREE_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_link_piobuf(
+ __in efx_nic_t *enp,
+ __in uint32_t vi_index,
+ __in efx_piobuf_handle_t handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
+ MC_CMD_LINK_PIOBUF_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LINK_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle);
+ MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_unlink_piobuf(
+ __in efx_nic_t *enp,
+ __in uint32_t vi_index)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
+ MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static void
+hunt_nic_alloc_piobufs(
+ __in efx_nic_t *enp,
+ __in uint32_t max_piobuf_count)
+{
+ efx_piobuf_handle_t *handlep;
+ unsigned int i;
+ int rc;
+
+ EFSYS_ASSERT3U(max_piobuf_count, <=,
+ EFX_ARRAY_SIZE(enp->en_u.hunt.enu_piobuf_handle));
+
+ enp->en_u.hunt.enu_piobuf_count = 0;
+
+ for (i = 0; i < max_piobuf_count; i++) {
+ handlep = &enp->en_u.hunt.enu_piobuf_handle[i];
+
+ if ((rc = efx_mcdi_alloc_piobuf(enp, handlep)) != 0)
+ goto fail1;
+
+ enp->en_u.hunt.enu_pio_alloc_map[i] = 0;
+ enp->en_u.hunt.enu_piobuf_count++;
+ }
+
+ return;
+
+fail1:
+ for (i = 0; i < enp->en_u.hunt.enu_piobuf_count; i++) {
+ handlep = &enp->en_u.hunt.enu_piobuf_handle[i];
+
+ efx_mcdi_free_piobuf(enp, *handlep);
+ *handlep = EFX_PIOBUF_HANDLE_INVALID;
+ }
+ enp->en_u.hunt.enu_piobuf_count = 0;
+}
+
+
+static void
+hunt_nic_free_piobufs(
+ __in efx_nic_t *enp)
+{
+ efx_piobuf_handle_t *handlep;
+ unsigned int i;
+
+ for (i = 0; i < enp->en_u.hunt.enu_piobuf_count; i++) {
+ handlep = &enp->en_u.hunt.enu_piobuf_handle[i];
+
+ efx_mcdi_free_piobuf(enp, *handlep);
+ *handlep = EFX_PIOBUF_HANDLE_INVALID;
+ }
+ enp->en_u.hunt.enu_piobuf_count = 0;
+}
+
+/* Sub-allocate a block from a piobuf */
+ __checkReturn int
+hunt_nic_pio_alloc(
+ __inout efx_nic_t *enp,
+ __out uint32_t *bufnump,
+ __out efx_piobuf_handle_t *handlep,
+ __out uint32_t *blknump,
+ __out uint32_t *offsetp,
+ __out size_t *sizep)
+{
+ efx_drv_cfg_t *edcp = &enp->en_drv_cfg;
+ uint32_t blk_per_buf;
+ uint32_t buf, blk;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+ EFSYS_ASSERT(bufnump);
+ EFSYS_ASSERT(handlep);
+ EFSYS_ASSERT(blknump);
+ EFSYS_ASSERT(offsetp);
+ EFSYS_ASSERT(sizep);
+
+ if ((edcp->edc_pio_alloc_size == 0) ||
+ (enp->en_u.hunt.enu_piobuf_count == 0)) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+ blk_per_buf = HUNT_PIOBUF_SIZE / edcp->edc_pio_alloc_size;
+
+ for (buf = 0; buf < enp->en_u.hunt.enu_piobuf_count; buf++) {
+ uint32_t *map = &enp->en_u.hunt.enu_pio_alloc_map[buf];
+
+ if (~(*map) == 0)
+ continue;
+
+ EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map)));
+ for (blk = 0; blk < blk_per_buf; blk++) {
+ if ((*map & (1u << blk)) == 0) {
+ *map |= (1u << blk);
+ goto done;
+ }
+ }
+ }
+ rc = ENOMEM;
+ goto fail2;
+
+done:
+ *handlep = enp->en_u.hunt.enu_piobuf_handle[buf];
+ *bufnump = buf;
+ *blknump = blk;
+ *sizep = edcp->edc_pio_alloc_size;
+ *offsetp = blk * (*sizep);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/* Free a piobuf sub-allocated block */
+ __checkReturn int
+hunt_nic_pio_free(
+ __inout efx_nic_t *enp,
+ __in uint32_t bufnum,
+ __in uint32_t blknum)
+{
+ uint32_t *map;
+ int rc;
+
+ if ((bufnum >= enp->en_u.hunt.enu_piobuf_count) ||
+ (blknum >= (8 * sizeof (*map)))) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ map = &enp->en_u.hunt.enu_pio_alloc_map[bufnum];
+ if ((*map & (1u << blknum)) == 0) {
+ rc = ENOENT;
+ goto fail2;
+ }
+ *map &= ~(1u << blknum);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nic_pio_link(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index,
+ __in efx_piobuf_handle_t handle)
+{
+ return (efx_mcdi_link_piobuf(enp, vi_index, handle));
+}
+
+ __checkReturn int
+hunt_nic_pio_unlink(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index)
+{
+ return (efx_mcdi_unlink_piobuf(enp, vi_index));
+}
+
+static __checkReturn int
+hunt_get_datapath_caps(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_dword_t datapath_capabilities;
+ int rc;
+
+ if ((rc = efx_mcdi_get_capabilities(enp, &datapath_capabilities)) != 0)
+ goto fail1;
+
+ /*
+ * Huntington RXDP firmware inserts a 0 or 14 byte prefix.
+ * We only support the 14 byte prefix here.
+ */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14) != 1) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+ encp->enc_rx_prefix_size = 14;
+
+ /* Check if the firmware supports TSO */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_TX_TSO) == 1)
+ encp->enc_fw_assisted_tso_enabled = B_TRUE;
+ else
+ encp->enc_fw_assisted_tso_enabled = B_FALSE;
+
+ /* Check if the firmware has vadapter/vport/vswitch support */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_EVB) == 1)
+ encp->enc_datapath_cap_evb = B_TRUE;
+ else
+ encp->enc_datapath_cap_evb = B_FALSE;
+
+ /* Check if the firmware supports VLAN insertion */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_TX_VLAN_INSERTION) == 1)
+ encp->enc_hw_tx_insert_vlan_enabled = B_TRUE;
+ else
+ encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
+
+ /* Check if the firmware supports RX event batching */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_RX_BATCHING) == 1) {
+ encp->enc_rx_batching_enabled = B_TRUE;
+ encp->enc_rx_batch_max = 16;
+ } else {
+ encp->enc_rx_batching_enabled = B_FALSE;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * The external port mapping is a one-based numbering of the external
+ * connectors on the board. It does not distinguish off-board separated
+ * outputs such as multi-headed cables.
+ * The number of ports that map to each external port connector
+ * on the board is determined by the chip family and the port modes to
+ * which the NIC can be configured. The mapping table lists modes with
+ * port numbering requirements in increasing order.
+ */
+static struct {
+ efx_family_t family;
+ uint32_t modes_mask;
+ uint32_t stride;
+} __hunt_external_port_mappings[] = {
+ /* Supported modes requiring 1 output per port */
+ {
+ EFX_FAMILY_HUNTINGTON,
+ (1 << TLV_PORT_MODE_10G) |
+ (1 << TLV_PORT_MODE_40G) |
+ (1 << TLV_PORT_MODE_10G_10G) |
+ (1 << TLV_PORT_MODE_40G_40G),
+ 1
+ },
+ /* Supported modes requiring 2 outputs per port */
+ {
+ EFX_FAMILY_HUNTINGTON,
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G) |
+ (1 << TLV_PORT_MODE_40G_10G_10G) |
+ (1 << TLV_PORT_MODE_10G_10G_40G),
+ 2
+ }
+};
+
+static __checkReturn int
+hunt_external_port_mapping(
+ __in efx_nic_t *enp,
+ __in uint32_t port,
+ __out uint8_t *external_portp)
+{
+ int rc;
+ int i;
+ uint32_t port_modes;
+ uint32_t matches;
+ uint32_t stride = 1; /* default 1-1 mapping */
+
+ if ((rc = efx_mcdi_get_port_modes(enp, &port_modes)) != 0) {
+ /* No port mode information available - use default mapping */
+ goto out;
+ }
+
+ /*
+ * Infer the internal port -> external port mapping from
+ * the possible port modes for this NIC.
+ */
+ for (i = 0; i < EFX_ARRAY_SIZE(__hunt_external_port_mappings); ++i) {
+ if (__hunt_external_port_mappings[i].family !=
+ enp->en_family)
+ continue;
+ matches = (__hunt_external_port_mappings[i].modes_mask &
+ port_modes);
+ if (matches != 0) {
+ stride = __hunt_external_port_mappings[i].stride;
+ port_modes &= ~matches;
+ }
+ }
+
+ if (port_modes != 0) {
+ /* Some advertised modes are not supported */
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+out:
+ /*
+ * Scale as required by last matched mode and then convert to
+ * one-based numbering
+ */
+ *external_portp = (uint8_t)(port / stride) + 1;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+hunt_board_cfg(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint8_t mac_addr[6];
+ uint32_t board_type = 0;
+ hunt_link_state_t hls;
+ efx_port_t *epp = &(enp->en_port);
+ uint32_t port;
+ uint32_t pf;
+ uint32_t vf;
+ uint32_t mask;
+ uint32_t flags;
+ uint32_t sysclk;
+ uint32_t base, nvec;
+ int rc;
+
+ if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0)
+ goto fail1;
+
+ /*
+ * NOTE: The MCDI protocol numbers ports from zero.
+ * The common code MCDI interface numbers ports from one.
+ */
+ emip->emi_port = port + 1;
+
+ if ((rc = hunt_external_port_mapping(enp, port,
+ &encp->enc_external_port)) != 0)
+ goto fail2;
+
+ /*
+ * Get PCIe function number from firmware (used for
+ * per-function privilege and dynamic config info).
+ * - PCIe PF: pf = PF number, vf = 0xffff.
+ * - PCIe VF: pf = parent PF, vf = VF number.
+ */
+ if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0)
+ goto fail3;
+
+ encp->enc_pf = pf;
+ encp->enc_vf = vf;
+
+ /* MAC address for this function */
+ if (EFX_PCI_FUNCTION_IS_PF(encp)) {
+ rc = efx_mcdi_get_mac_address_pf(enp, mac_addr);
+ } else {
+ rc = efx_mcdi_get_mac_address_vf(enp, mac_addr);
+ }
+ if ((rc == 0) && (mac_addr[0] & 0x02)) {
+ /*
+ * If the static config does not include a global MAC address
+ * pool then the board may return a locally administered MAC
+ * address (this should only happen on incorrectly programmed
+ * boards).
+ */
+ rc = EINVAL;
+ }
+ if (rc != 0)
+ goto fail4;
+
+ EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
+
+ /* Board configuration */
+ rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL);
+ if (rc != 0) {
+ /* Unprivileged functions may not be able to read board cfg */
+ if (rc == EACCES)
+ board_type = 0;
+ else
+ goto fail5;
+ }
+
+ encp->enc_board_type = board_type;
+ encp->enc_clk_mult = 1; /* not used for Huntington */
+
+ /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
+ if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
+ goto fail6;
+
+ /* Obtain the default PHY advertised capabilities */
+ if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ goto fail7;
+ epp->ep_default_adv_cap_mask = hls.hls_adv_cap_mask;
+ epp->ep_adv_cap_mask = hls.hls_adv_cap_mask;
+
+ /*
+ * Enable firmware workarounds for hardware errata.
+ * Expected responses are:
+ * - 0 (zero):
+ * Success: workaround enabled or disabled as requested.
+ * - MC_CMD_ERR_ENOSYS (reported as ENOTSUP):
+ * Firmware does not support the MC_CMD_WORKAROUND request.
+ * (assume that the workaround is not supported).
+ * - MC_CMD_ERR_ENOENT (reported as ENOENT):
+ * Firmware does not support the requested workaround.
+ * - MC_CMD_ERR_EPERM (reported as EACCES):
+ * Unprivileged function cannot enable/disable workarounds.
+ *
+ * See efx_mcdi_request_errcode() for MCDI error translations.
+ */
+
+ /*
+ * If the bug35388 workaround is enabled, then use an indirect access
+ * method to avoid unsafe EVQ writes.
+ */
+ rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG35388, B_TRUE,
+ NULL);
+ if ((rc == 0) || (rc == EACCES))
+ encp->enc_bug35388_workaround = B_TRUE;
+ else if ((rc == ENOTSUP) || (rc == ENOENT))
+ encp->enc_bug35388_workaround = B_FALSE;
+ else
+ goto fail8;
+
+ /*
+ * If the bug41750 workaround is enabled, then do not test interrupts,
+ * as the test will fail (seen with Greenport controllers).
+ */
+ rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG41750, B_TRUE,
+ NULL);
+ if (rc == 0) {
+ encp->enc_bug41750_workaround = B_TRUE;
+ } else if (rc == EACCES) {
+ /* Assume a controller with 40G ports needs the workaround. */
+ if (epp->ep_default_adv_cap_mask & EFX_PHY_CAP_40000FDX)
+ encp->enc_bug41750_workaround = B_TRUE;
+ else
+ encp->enc_bug41750_workaround = B_FALSE;
+ } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
+ encp->enc_bug41750_workaround = B_FALSE;
+ } else {
+ goto fail9;
+ }
+ if (EFX_PCI_FUNCTION_IS_VF(encp)) {
+ /* Interrupt testing does not work for VFs. See bug50084. */
+ encp->enc_bug41750_workaround = B_TRUE;
+ }
+
+ /*
+ * If the bug26807 workaround is enabled, then firmware has enabled
+ * support for chained multicast filters. Firmware will reset (FLR)
+ * functions which have filters in the hardware filter table when the
+ * workaround is enabled/disabled.
+ *
+ * We must recheck if the workaround is enabled after inserting the
+ * first hardware filter, in case it has been changed since this check.
+ */
+ rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807,
+ B_TRUE, &flags);
+ if (rc == 0) {
+ encp->enc_bug26807_workaround = B_TRUE;
+ if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) {
+ /*
+ * Other functions had installed filters before the
+ * workaround was enabled, and they have been reset
+ * by firmware.
+ */
+ EFSYS_PROBE(bug26807_workaround_flr_done);
+ /* FIXME: bump MC warm boot count ? */
+ }
+ } else if (rc == EACCES) {
+ /*
+ * Unprivileged functions cannot enable the workaround in older
+ * firmware.
+ */
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else {
+ goto fail10;
+ }
+
+ /* Get sysclk frequency (in MHz). */
+ if ((rc = efx_mcdi_get_clock(enp, &sysclk)) != 0)
+ goto fail11;
+
+ /*
+ * The timer quantum is 1536 sysclk cycles, documented for the
+ * EV_TMR_VAL field of EV_TIMER_TBL. Scale for MHz and ns units.
+ */
+ encp->enc_evq_timer_quantum_ns = 1536000UL / sysclk; /* 1536 cycles */
+ if (encp->enc_bug35388_workaround) {
+ encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
+ ERF_DD_EVQ_IND_TIMER_VAL_WIDTH) / 1000;
+ } else {
+ encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
+ FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
+ }
+
+ /* Check capabilities of running datapath firmware */
+ if ((rc = hunt_get_datapath_caps(enp)) != 0)
+ goto fail12;
+
+ /* Alignment for receive packet DMA buffers */
+ encp->enc_rx_buf_align_start = 1;
+ encp->enc_rx_buf_align_end = 64; /* RX DMA end padding */
+
+ /* Alignment for WPTR updates */
+ encp->enc_rx_push_align = HUNTINGTON_RX_WPTR_ALIGN;
+
+ /*
+ * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
+ * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
+ * resources (allocated to this PCIe function), which is zero until
+ * after we have allocated VIs.
+ */
+ encp->enc_evq_limit = 1024;
+ encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
+ encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
+
+ encp->enc_buftbl_limit = 0xFFFFFFFF;
+
+ encp->enc_piobuf_limit = HUNT_PIOBUF_NBUFS;
+ encp->enc_piobuf_size = HUNT_PIOBUF_SIZE;
+
+ /*
+ * Get the current privilege mask. Note that this may be modified
+ * dynamically, so this value is informational only. DO NOT use
+ * the privilege mask to check for sufficient privileges, as that
+ * can result in time-of-check/time-of-use bugs.
+ */
+ if ((rc = efx_mcdi_privilege_mask(enp, pf, vf, &mask)) != 0)
+ goto fail13;
+
+ encp->enc_privilege_mask = mask;
+
+ /* Get interrupt vector limits */
+ if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) {
+ if (EFX_PCI_FUNCTION_IS_PF(encp))
+ goto fail14;
+
+ /* Ignore error (cannot query vector limits from a VF). */
+ base = 0;
+ nvec = 1024;
+ }
+ encp->enc_intr_vec_base = base;
+ encp->enc_intr_limit = nvec;
+
+ /*
+ * Maximum number of bytes into the frame the TCP header can start for
+ * firmware assisted TSO to work.
+ */
+ encp->enc_tx_tso_tcp_header_offset_limit = 208;
+
+ return (0);
+
+fail14:
+ EFSYS_PROBE(fail14);
+fail13:
+ EFSYS_PROBE(fail13);
+fail12:
+ EFSYS_PROBE(fail12);
+fail11:
+ EFSYS_PROBE(fail11);
+fail10:
+ EFSYS_PROBE(fail10);
+fail9:
+ EFSYS_PROBE(fail9);
+fail8:
+ EFSYS_PROBE(fail8);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+hunt_nic_probe(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* Read and clear any assertion state */
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
+ goto fail1;
+
+ /* Exit the assertion handler */
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
+ if (rc != EACCES)
+ goto fail2;
+
+ if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
+ goto fail3;
+
+ if ((rc = hunt_board_cfg(enp)) != 0)
+ if (rc != EACCES)
+ goto fail4;
+
+ /*
+ * Set default driver config limits (based on board config).
+ *
+ * FIXME: For now allocate a fixed number of VIs which is likely to be
+ * sufficient and small enough to allow multiple functions on the same
+ * port.
+ */
+ edcp->edc_min_vi_count = edcp->edc_max_vi_count =
+ MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
+
+ /* The client driver must configure and enable PIO buffer support */
+ edcp->edc_max_piobuf_count = 0;
+ edcp->edc_pio_alloc_size = 0;
+
+#if EFSYS_OPT_MAC_STATS
+ /* Wipe the MAC statistics */
+ if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
+ goto fail5;
+#endif
+
+#if EFSYS_OPT_LOOPBACK
+ if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
+ goto fail6;
+#endif
+
+#if EFSYS_OPT_MON_STATS
+ if ((rc = mcdi_mon_cfg_build(enp)) != 0) {
+ /* Unprivileged functions do not have access to sensors */
+ if (rc != EACCES)
+ goto fail7;
+ }
+#endif
+
+ encp->enc_features = enp->en_features;
+
+ return (0);
+
+#if EFSYS_OPT_MON_STATS
+fail7:
+ EFSYS_PROBE(fail7);
+#endif
+#if EFSYS_OPT_LOOPBACK
+fail6:
+ EFSYS_PROBE(fail6);
+#endif
+#if EFSYS_OPT_MAC_STATS
+fail5:
+ EFSYS_PROBE(fail5);
+#endif
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nic_set_drv_limits(
+ __inout efx_nic_t *enp,
+ __in efx_drv_limits_t *edlp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ uint32_t min_evq_count, max_evq_count;
+ uint32_t min_rxq_count, max_rxq_count;
+ uint32_t min_txq_count, max_txq_count;
+ int rc;
+
+ if (edlp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Get minimum required and maximum usable VI limits */
+ min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
+ min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
+ min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
+
+ edcp->edc_min_vi_count =
+ MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
+
+ max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
+ max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
+ max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
+
+ edcp->edc_max_vi_count =
+ MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
+
+ /*
+ * Check limits for sub-allocated piobuf blocks.
+ * PIO is optional, so don't fail if the limits are incorrect.
+ */
+ if ((encp->enc_piobuf_size == 0) ||
+ (encp->enc_piobuf_limit == 0) ||
+ (edlp->edl_min_pio_alloc_size == 0) ||
+ (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) {
+ /* Disable PIO */
+ edcp->edc_max_piobuf_count = 0;
+ edcp->edc_pio_alloc_size = 0;
+ } else {
+ uint32_t blk_size, blk_count, blks_per_piobuf;
+
+ blk_size =
+ MAX(edlp->edl_min_pio_alloc_size, HUNT_MIN_PIO_ALLOC_SIZE);
+
+ blks_per_piobuf = encp->enc_piobuf_size / blk_size;
+ EFSYS_ASSERT3U(blks_per_piobuf, <=, 32);
+
+ blk_count = (encp->enc_piobuf_limit * blks_per_piobuf);
+
+ /* A zero max pio alloc count means unlimited */
+ if ((edlp->edl_max_pio_alloc_count > 0) &&
+ (edlp->edl_max_pio_alloc_count < blk_count)) {
+ blk_count = edlp->edl_max_pio_alloc_count;
+ }
+
+ edcp->edc_pio_alloc_size = blk_size;
+ edcp->edc_max_piobuf_count =
+ (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+hunt_nic_reset(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
+ MC_CMD_ENTITY_RESET_OUT_LEN)];
+ int rc;
+
+ /* hunt_nic_reset() is called to recover from BADASSERT failures. */
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
+ goto fail1;
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
+ goto fail2;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ENTITY_RESET;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN;
+
+ MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG,
+ ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail3;
+ }
+
+ /* Clear RX/TX DMA queue errors */
+ enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nic_init(
+ __in efx_nic_t *enp)
+{
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ uint32_t min_vi_count, max_vi_count;
+ uint32_t vi_count, vi_base;
+ uint32_t i;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* Enable reporting of some events (e.g. link change) */
+ if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
+ goto fail1;
+
+ /* Allocate (optional) on-chip PIO buffers */
+ hunt_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count);
+
+ /*
+ * For best performance, PIO writes should use a write-combined
+ * (WC) memory mapping. Using a separate WC mapping for the PIO
+ * aperture of each VI would be a burden to drivers (and not
+ * possible if the host page size is >4Kbyte).
+ *
+ * To avoid this we use a single uncached (UC) mapping for VI
+ * register access, and a single WC mapping for extra VIs used
+ * for PIO writes.
+ *
+ * Each piobuf must be linked to a VI in the WC mapping, and to
+ * each VI that is using a sub-allocated block from the piobuf.
+ */
+ min_vi_count = edcp->edc_min_vi_count;
+ max_vi_count = edcp->edc_max_vi_count + enp->en_u.hunt.enu_piobuf_count;
+
+ /* Ensure that the previously attached driver's VIs are freed */
+ if ((rc = efx_mcdi_free_vis(enp)) != 0)
+ goto fail2;
+
+ /*
+ * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
+ * fails then retrying the request for fewer VI resources may succeed.
+ */
+ vi_count = 0;
+ if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
+ &vi_base, &vi_count)) != 0)
+ goto fail3;
+
+ EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
+
+ if (vi_count < min_vi_count) {
+ rc = ENOMEM;
+ goto fail4;
+ }
+
+ enp->en_u.hunt.enu_vi_base = vi_base;
+ enp->en_u.hunt.enu_vi_count = vi_count;
+
+ if (vi_count < min_vi_count + enp->en_u.hunt.enu_piobuf_count) {
+ /* Not enough extra VIs to map piobufs */
+ hunt_nic_free_piobufs(enp);
+ }
+
+ enp->en_u.hunt.enu_pio_write_vi_base =
+ vi_count - enp->en_u.hunt.enu_piobuf_count;
+
+ /* Save UC memory mapping details */
+ enp->en_u.hunt.enu_uc_mem_map_offset = 0;
+ if (enp->en_u.hunt.enu_piobuf_count > 0) {
+ enp->en_u.hunt.enu_uc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_u.hunt.enu_pio_write_vi_base);
+ } else {
+ enp->en_u.hunt.enu_uc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_u.hunt.enu_vi_count);
+ }
+
+ /* Save WC memory mapping details */
+ enp->en_u.hunt.enu_wc_mem_map_offset =
+ enp->en_u.hunt.enu_uc_mem_map_offset +
+ enp->en_u.hunt.enu_uc_mem_map_size;
+
+ enp->en_u.hunt.enu_wc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_u.hunt.enu_piobuf_count);
+
+ /* Link piobufs to extra VIs in WC mapping */
+ if (enp->en_u.hunt.enu_piobuf_count > 0) {
+ for (i = 0; i < enp->en_u.hunt.enu_piobuf_count; i++) {
+ rc = efx_mcdi_link_piobuf(enp,
+ enp->en_u.hunt.enu_pio_write_vi_base + i,
+ enp->en_u.hunt.enu_piobuf_handle[i]);
+ if (rc != 0)
+ break;
+ }
+ }
+
+ /* Allocate a vAdapter attached to our upstream vPort/pPort */
+ if ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0)
+ goto fail5;
+
+ enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
+
+ return (0);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+
+ hunt_nic_free_piobufs(enp);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nic_get_vi_pool(
+ __in efx_nic_t *enp,
+ __out uint32_t *vi_countp)
+{
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * Report VIs that the client driver can use.
+ * Do not include VIs used for PIO buffer writes.
+ */
+ *vi_countp = enp->en_u.hunt.enu_pio_write_vi_base;
+
+ return (0);
+}
+
+ __checkReturn int
+hunt_nic_get_bar_region(
+ __in efx_nic_t *enp,
+ __in efx_nic_region_t region,
+ __out uint32_t *offsetp,
+ __out size_t *sizep)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * TODO: Specify host memory mapping alignment and granularity
+ * in efx_drv_limits_t so that they can be taken into account
+ * when allocating extra VIs for PIO writes.
+ */
+ switch (region) {
+ case EFX_REGION_VI:
+ /* UC mapped memory BAR region for VI registers */
+ *offsetp = enp->en_u.hunt.enu_uc_mem_map_offset;
+ *sizep = enp->en_u.hunt.enu_uc_mem_map_size;
+ break;
+
+ case EFX_REGION_PIO_WRITE_VI:
+ /* WC mapped memory BAR region for piobuf writes */
+ *offsetp = enp->en_u.hunt.enu_wc_mem_map_offset;
+ *sizep = enp->en_u.hunt.enu_wc_mem_map_size;
+ break;
+
+ default:
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_nic_fini(
+ __in efx_nic_t *enp)
+{
+ (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
+ enp->en_vport_id = 0;
+
+ /* FIXME: do we need to unlink piobufs ? */
+ hunt_nic_free_piobufs(enp);
+
+ (void) efx_mcdi_free_vis(enp);
+ enp->en_u.hunt.enu_vi_count = 0;
+}
+
+ void
+hunt_nic_unprobe(
+ __in efx_nic_t *enp)
+{
+#if EFSYS_OPT_MON_STATS
+ mcdi_mon_cfg_free(enp);
+#endif /* EFSYS_OPT_MON_STATS */
+ (void) efx_mcdi_drv_attach(enp, B_FALSE);
+}
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+hunt_nic_register_test(
+ __in efx_nic_t *enp)
+{
+ int rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(enp))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_nvram.c b/sys/dev/sfxge/common/hunt_nvram.c
new file mode 100644
index 000000000000..3e130f4a51b0
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_nvram.c
@@ -0,0 +1,1538 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_regs.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
+
+#include "ef10_tlv_layout.h"
+
+/* Cursor for TLV partition format */
+typedef struct tlv_cursor_s {
+ uint32_t *block; /* Base of data block */
+ uint32_t *current; /* Cursor position */
+ uint32_t *end; /* End tag position */
+ uint32_t *limit; /* Last dword of data block */
+} tlv_cursor_t;
+
+static __checkReturn int
+tlv_validate_state(
+ __in tlv_cursor_t *cursor);
+
+
+/*
+ * Operations on TLV formatted partition data.
+ */
+static uint32_t
+tlv_tag(
+ __in tlv_cursor_t *cursor)
+{
+ uint32_t dword, tag;
+
+ dword = cursor->current[0];
+ tag = __LE_TO_CPU_32(dword);
+
+ return (tag);
+}
+
+static size_t
+tlv_length(
+ __in tlv_cursor_t *cursor)
+{
+ uint32_t dword, length;
+
+ if (tlv_tag(cursor) == TLV_TAG_END)
+ return (0);
+
+ dword = cursor->current[1];
+ length = __LE_TO_CPU_32(dword);
+
+ return ((size_t)length);
+}
+
+static uint8_t *
+tlv_value(
+ __in tlv_cursor_t *cursor)
+{
+ if (tlv_tag(cursor) == TLV_TAG_END)
+ return (NULL);
+
+ return ((uint8_t *)(&cursor->current[2]));
+}
+
+static uint8_t *
+tlv_item(
+ __in tlv_cursor_t *cursor)
+{
+ if (tlv_tag(cursor) == TLV_TAG_END)
+ return (NULL);
+
+ return ((uint8_t *)cursor->current);
+}
+
+/*
+ * TLV item DWORD length is tag + length + value (rounded up to DWORD)
+ * equivalent to tlv_n_words_for_len in mc-comms tlv.c
+ */
+#define TLV_DWORD_COUNT(length) \
+ (1 + 1 + (((length) + sizeof (uint32_t) - 1) / sizeof (uint32_t)))
+
+
+static uint32_t *
+tlv_next_item_ptr(
+ __in tlv_cursor_t *cursor)
+{
+ uint32_t length;
+
+ length = tlv_length(cursor);
+
+ return (cursor->current + TLV_DWORD_COUNT(length));
+}
+
+static int
+tlv_advance(
+ __in tlv_cursor_t *cursor)
+{
+ int rc;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ if (cursor->current == cursor->end) {
+ /* No more tags after END tag */
+ cursor->current = NULL;
+ rc = ENOENT;
+ goto fail2;
+ }
+
+ /* Advance to next item and validate */
+ cursor->current = tlv_next_item_ptr(cursor);
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static int
+tlv_rewind(
+ __in tlv_cursor_t *cursor)
+{
+ int rc;
+
+ cursor->current = cursor->block;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static int
+tlv_find(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t tag)
+{
+ int rc;
+
+ rc = tlv_rewind(cursor);
+ while (rc == 0) {
+ if (tlv_tag(cursor) == tag)
+ break;
+
+ rc = tlv_advance(cursor);
+ }
+ return (rc);
+}
+
+static __checkReturn int
+tlv_validate_state(
+ __in tlv_cursor_t *cursor)
+{
+ int rc;
+
+ /* Check cursor position */
+ if (cursor->current < cursor->block) {
+ rc = EINVAL;
+ goto fail1;
+ }
+ if (cursor->current > cursor->limit) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ if (tlv_tag(cursor) != TLV_TAG_END) {
+ /* Check current item has space for tag and length */
+ if (cursor->current > (cursor->limit - 2)) {
+ cursor->current = NULL;
+ rc = EFAULT;
+ goto fail3;
+ }
+
+ /* Check we have value data for current item and another tag */
+ if (tlv_next_item_ptr(cursor) > (cursor->limit - 1)) {
+ cursor->current = NULL;
+ rc = EFAULT;
+ goto fail4;
+ }
+ }
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static int
+tlv_init_cursor(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t *block,
+ __in uint32_t *limit)
+{
+ cursor->block = block;
+ cursor->limit = limit;
+
+ cursor->current = cursor->block;
+ cursor->end = NULL;
+
+ return (tlv_validate_state(cursor));
+}
+
+static int
+tlv_init_cursor_from_size(
+ __in tlv_cursor_t *cursor,
+ __in uint8_t *block,
+ __in size_t size)
+{
+ uint32_t *limit;
+ limit = (uint32_t *)(block + size - sizeof (uint32_t));
+ return (tlv_init_cursor(cursor, (uint32_t *)block, limit));
+}
+
+static int
+tlv_require_end(
+ __in tlv_cursor_t *cursor)
+{
+ uint32_t *pos;
+ int rc;
+
+ if (cursor->end == NULL) {
+ pos = cursor->current;
+ if ((rc = tlv_find(cursor, TLV_TAG_END)) != 0)
+ goto fail1;
+
+ cursor->end = cursor->current;
+ cursor->current = pos;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static size_t
+tlv_block_length_used(
+ __in tlv_cursor_t *cursor)
+{
+ int rc;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ if ((rc = tlv_require_end(cursor)) != 0)
+ goto fail2;
+
+ /* Return space used (including the END tag) */
+ return (cursor->end + 1 - cursor->block) * sizeof (uint32_t);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (0);
+}
+
+
+static __checkReturn uint32_t *
+tlv_write(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t tag,
+ __in_bcount(size) uint8_t *data,
+ __in size_t size)
+{
+ uint32_t len = size;
+ uint32_t *ptr;
+
+ ptr = cursor->current;
+
+ *ptr++ = __CPU_TO_LE_32(tag);
+ *ptr++ = __CPU_TO_LE_32(len);
+
+ if (len > 0) {
+ ptr[(len - 1) / sizeof (uint32_t)] = 0;
+ memcpy(ptr, data, len);
+ ptr += P2ROUNDUP(len, sizeof (uint32_t)) / sizeof (*ptr);
+ }
+
+ return (ptr);
+}
+
+static __checkReturn int
+tlv_insert(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t tag,
+ __in uint8_t *data,
+ __in size_t size)
+{
+ unsigned int delta;
+ int rc;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ if ((rc = tlv_require_end(cursor)) != 0)
+ goto fail2;
+
+ if (tag == TLV_TAG_END) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ delta = TLV_DWORD_COUNT(size);
+ if (cursor->end + 1 + delta > cursor->limit) {
+ rc = ENOSPC;
+ goto fail4;
+ }
+
+ /* Move data up: new space at cursor->current */
+ memmove(cursor->current + delta, cursor->current,
+ (cursor->end + 1 - cursor->current) * sizeof (uint32_t));
+
+ /* Adjust the end pointer */
+ cursor->end += delta;
+
+ /* Write new TLV item */
+ tlv_write(cursor, tag, data, size);
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+tlv_modify(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t tag,
+ __in uint8_t *data,
+ __in size_t size)
+{
+ uint32_t *pos;
+ unsigned int old_ndwords;
+ unsigned int new_ndwords;
+ unsigned int delta;
+ int rc;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ if (tlv_tag(cursor) == TLV_TAG_END) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ if (tlv_tag(cursor) != tag) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ old_ndwords = TLV_DWORD_COUNT(tlv_length(cursor));
+ new_ndwords = TLV_DWORD_COUNT(size);
+
+ if ((rc = tlv_require_end(cursor)) != 0)
+ goto fail4;
+
+ if (new_ndwords > old_ndwords) {
+ /* Expand space used for TLV item */
+ delta = new_ndwords - old_ndwords;
+ pos = cursor->current + old_ndwords;
+
+ if (cursor->end + 1 + delta > cursor->limit) {
+ rc = ENOSPC;
+ goto fail5;
+ }
+
+ /* Move up: new space at (cursor->current + old_ndwords) */
+ memmove(pos + delta, pos,
+ (cursor->end + 1 - pos) * sizeof (uint32_t));
+
+ /* Adjust the end pointer */
+ cursor->end += delta;
+
+ } else if (new_ndwords < old_ndwords) {
+ /* Shrink space used for TLV item */
+ delta = old_ndwords - new_ndwords;
+ pos = cursor->current + new_ndwords;
+
+ /* Move down: remove words at (cursor->current + new_ndwords) */
+ memmove(pos, pos + delta,
+ (cursor->end + 1 - pos) * sizeof (uint32_t));
+
+ /* Zero the new space at the end of the TLV chain */
+ memset(cursor->end + 1 - delta, 0, delta * sizeof (uint32_t));
+
+ /* Adjust the end pointer */
+ cursor->end -= delta;
+ }
+
+ /* Write new data */
+ tlv_write(cursor, tag, data, size);
+
+ return (0);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/* Validate TLV formatted partition contents (before writing to flash) */
+ __checkReturn int
+efx_nvram_tlv_validate(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size)
+{
+ tlv_cursor_t cursor;
+ struct tlv_partition_header *header;
+ struct tlv_partition_trailer *trailer;
+ size_t total_length;
+ uint32_t cksum;
+ int pos;
+ int rc;
+
+ EFX_STATIC_ASSERT(sizeof (*header) <= HUNTINGTON_NVRAM_CHUNK);
+
+ if ((partn_data == NULL) || (partn_size == 0)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* The partition header must be the first item (at offset zero) */
+ if ((rc = tlv_init_cursor_from_size(&cursor, partn_data,
+ partn_size)) != 0) {
+ rc = EFAULT;
+ goto fail2;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_PARTITION_HEADER) {
+ rc = EINVAL;
+ goto fail3;
+ }
+ header = (struct tlv_partition_header *)tlv_item(&cursor);
+
+ /* Check TLV partition length (includes the END tag) */
+ total_length = __LE_TO_CPU_32(header->total_length);
+ if (total_length > partn_size) {
+ rc = EFBIG;
+ goto fail4;
+ }
+
+ /* Check partition ends with PARTITION_TRAILER and END tags */
+ if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
+ rc = EINVAL;
+ goto fail5;
+ }
+ trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
+
+ if ((rc = tlv_advance(&cursor)) != 0) {
+ rc = EINVAL;
+ goto fail6;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_END) {
+ rc = EINVAL;
+ goto fail7;
+ }
+
+ /* Check generation counts are consistent */
+ if (trailer->generation != header->generation) {
+ rc = EINVAL;
+ goto fail8;
+ }
+
+ /* Verify partition checksum */
+ cksum = 0;
+ for (pos = 0; (size_t)pos < total_length; pos += sizeof (uint32_t)) {
+ cksum += *((uint32_t *)(partn_data + pos));
+ }
+ if (cksum != 0) {
+ rc = EINVAL;
+ goto fail9;
+ }
+
+ return (0);
+
+fail9:
+ EFSYS_PROBE(fail9);
+fail8:
+ EFSYS_PROBE(fail8);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/* Read and validate an entire TLV formatted partition */
+static __checkReturn int
+hunt_nvram_read_tlv_partition(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size)
+{
+ tlv_cursor_t cursor;
+ struct tlv_partition_header *header;
+ struct tlv_partition_trailer *trailer;
+ size_t total_length;
+ uint32_t cksum;
+ int pos;
+ int rc;
+
+ EFX_STATIC_ASSERT(sizeof (*header) <= HUNTINGTON_NVRAM_CHUNK);
+
+ if ((partn_data == NULL) || (partn_size == 0)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Read initial chunk of partition */
+ if ((rc = hunt_nvram_partn_read(enp, partn, 0, partn_data,
+ HUNTINGTON_NVRAM_CHUNK)) != 0) {
+ goto fail2;
+ }
+
+ /* The partition header must be the first item (at offset zero) */
+ if ((rc = tlv_init_cursor_from_size(&cursor, partn_data,
+ partn_size)) != 0) {
+ rc = EFAULT;
+ goto fail3;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_PARTITION_HEADER) {
+ rc = EINVAL;
+ goto fail4;
+ }
+ header = (struct tlv_partition_header *)tlv_item(&cursor);
+
+ /* Check TLV partition length (includes the END tag) */
+ total_length = __LE_TO_CPU_32(header->total_length);
+ if (total_length > partn_size) {
+ rc = EFBIG;
+ goto fail5;
+ }
+
+ /* Read the remaining partition content */
+ if (total_length > HUNTINGTON_NVRAM_CHUNK) {
+ if ((rc = hunt_nvram_partn_read(enp, partn,
+ HUNTINGTON_NVRAM_CHUNK,
+ partn_data + HUNTINGTON_NVRAM_CHUNK,
+ total_length - HUNTINGTON_NVRAM_CHUNK)) != 0)
+ goto fail6;
+ }
+
+ /* Check partition ends with PARTITION_TRAILER and END tags */
+ if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
+ rc = EINVAL;
+ goto fail7;
+ }
+ trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
+
+ if ((rc = tlv_advance(&cursor)) != 0) {
+ rc = EINVAL;
+ goto fail8;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_END) {
+ rc = EINVAL;
+ goto fail9;
+ }
+
+ /* Check data read from partition is consistent */
+ if (trailer->generation != header->generation) {
+ /*
+ * The partition data may have been modified between successive
+ * MCDI NVRAM_READ requests by the MC or another PCI function.
+ *
+ * The caller must retry to obtain consistent partition data.
+ */
+ rc = EAGAIN;
+ goto fail10;
+ }
+
+ /* Verify partition checksum */
+ cksum = 0;
+ for (pos = 0; (size_t)pos < total_length; pos += sizeof (uint32_t)) {
+ cksum += *((uint32_t *)(partn_data + pos));
+ }
+ if (cksum != 0) {
+ rc = EINVAL;
+ goto fail11;
+ }
+
+ return (0);
+
+fail11:
+ EFSYS_PROBE(fail11);
+fail10:
+ EFSYS_PROBE(fail10);
+fail9:
+ EFSYS_PROBE(fail9);
+fail8:
+ EFSYS_PROBE(fail8);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * Read a single TLV item from a host memory
+ * buffer containing a TLV formatted partition.
+ */
+ __checkReturn int
+hunt_nvram_buf_read_tlv(
+ __in efx_nic_t *enp,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size,
+ __in uint32_t tag,
+ __deref_out_bcount_opt(*sizep) caddr_t *datap,
+ __out size_t *sizep)
+{
+ tlv_cursor_t cursor;
+ caddr_t data;
+ size_t length;
+ caddr_t value;
+ int rc;
+
+ if ((partn_data == NULL) || (partn_size == 0)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Find requested TLV tag in partition data */
+ if ((rc = tlv_init_cursor_from_size(&cursor, partn_data,
+ partn_size)) != 0) {
+ rc = EFAULT;
+ goto fail2;
+ }
+ if ((rc = tlv_find(&cursor, tag)) != 0) {
+ rc = ENOENT;
+ goto fail3;
+ }
+ value = tlv_value(&cursor);
+ length = tlv_length(&cursor);
+
+ if (length == 0)
+ data = NULL;
+ else {
+ /* Copy out data from TLV item */
+ EFSYS_KMEM_ALLOC(enp->en_esip, length, data);
+ if (data == NULL) {
+ rc = ENOMEM;
+ goto fail4;
+ }
+ memcpy(data, value, length);
+ }
+
+ *datap = data;
+ *sizep = length;
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+
+/* Read a single TLV item from a TLV formatted partition */
+ __checkReturn int
+hunt_nvram_partn_read_tlv(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t tag,
+ __deref_out_bcount_opt(*sizep) caddr_t *datap,
+ __out size_t *sizep)
+{
+ caddr_t partn_data = NULL;
+ size_t partn_size = 0;
+ size_t length;
+ caddr_t data;
+ int retry;
+ int rc;
+
+ /* Allocate sufficient memory for the entire partition */
+ if ((rc = hunt_nvram_partn_size(enp, partn, &partn_size)) != 0)
+ goto fail1;
+
+ if (partn_size == 0) {
+ rc = ENOENT;
+ goto fail2;
+ }
+
+ EFSYS_KMEM_ALLOC(enp->en_esip, partn_size, partn_data);
+ if (partn_data == NULL) {
+ rc = ENOMEM;
+ goto fail3;
+ }
+
+ /*
+ * Read the entire TLV partition. Retry until consistent partition
+ * contents are returned. Inconsistent data may be read if:
+ * a) the partition contents are invalid
+ * b) the MC has rebooted while we were reading the partition
+ * c) the partition has been modified while we were reading it
+ * Limit retry attempts to ensure forward progress.
+ */
+ retry = 10;
+ do {
+ rc = hunt_nvram_read_tlv_partition(enp, partn,
+ partn_data, partn_size);
+ } while ((rc == EAGAIN) && (--retry > 0));
+
+ if (rc != 0) {
+ /* Failed to obtain consistent partition data */
+ goto fail4;
+ }
+
+ if ((rc = hunt_nvram_buf_read_tlv(enp, partn_data, partn_size,
+ tag, &data, &length)) != 0)
+ goto fail5;
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
+
+ *datap = data;
+ *sizep = length;
+
+ return (0);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * Add or update a single TLV item in a host memory buffer containing a TLV
+ * formatted partition.
+ */
+ __checkReturn int
+hunt_nvram_buf_write_tlv(
+ __inout_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size,
+ __in uint32_t tag,
+ __in_bcount(tag_size) caddr_t tag_data,
+ __in size_t tag_size,
+ __out size_t *total_lengthp)
+{
+ tlv_cursor_t cursor;
+ struct tlv_partition_header *header;
+ struct tlv_partition_trailer *trailer;
+ uint32_t generation;
+ uint32_t cksum;
+ int pos;
+ int rc;
+
+ /* The partition header must be the first item (at offset zero) */
+ if ((rc = tlv_init_cursor_from_size(&cursor, partn_data,
+ partn_size)) != 0) {
+ rc = EFAULT;
+ goto fail1;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_PARTITION_HEADER) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ header = (struct tlv_partition_header *)tlv_item(&cursor);
+
+ /* Update the TLV chain to contain the new data */
+ if ((rc = tlv_find(&cursor, tag)) == 0) {
+ /* Modify existing TLV item */
+ if ((rc = tlv_modify(&cursor, tag,
+ tag_data, tag_size)) != 0)
+ goto fail3;
+ } else {
+ /* Insert a new TLV item before the PARTITION_TRAILER */
+ rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER);
+ if (rc != 0) {
+ rc = EINVAL;
+ goto fail4;
+ }
+ if ((rc = tlv_insert(&cursor, tag,
+ tag_data, tag_size)) != 0) {
+ rc = EINVAL;
+ goto fail5;
+ }
+ }
+
+ /* Find the trailer tag */
+ if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
+ rc = EINVAL;
+ goto fail6;
+ }
+ trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
+
+ /* Update PARTITION_HEADER and PARTITION_TRAILER fields */
+ *total_lengthp = tlv_block_length_used(&cursor);
+ EFSYS_ASSERT3U(*total_lengthp, <=, partn_size);
+ generation = __LE_TO_CPU_32(header->generation) + 1;
+
+ header->total_length = __CPU_TO_LE_32(*total_lengthp);
+ header->generation = __CPU_TO_LE_32(generation);
+ trailer->generation = __CPU_TO_LE_32(generation);
+
+ /* Recompute PARTITION_TRAILER checksum */
+ trailer->checksum = 0;
+ cksum = 0;
+ for (pos = 0; (size_t)pos < *total_lengthp; pos += sizeof (uint32_t)) {
+ cksum += *((uint32_t *)(partn_data + pos));
+ }
+ trailer->checksum = ~cksum + 1;
+
+ return (0);
+
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/* Add or update a single TLV item in a TLV formatted partition */
+ __checkReturn int
+hunt_nvram_partn_write_tlv(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t tag,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ size_t partn_size;
+ caddr_t partn_data;
+ size_t total_length;
+ int rc;
+
+ EFSYS_ASSERT3U(partn, ==, NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG);
+
+ /* Allocate sufficient memory for the entire partition */
+ if ((rc = hunt_nvram_partn_size(enp, partn, &partn_size)) != 0)
+ goto fail1;
+
+ EFSYS_KMEM_ALLOC(enp->en_esip, partn_size, partn_data);
+ if (partn_data == NULL) {
+ rc = ENOMEM;
+ goto fail2;
+ }
+
+ /* Lock the partition */
+ if ((rc = hunt_nvram_partn_lock(enp, partn)) != 0)
+ goto fail3;
+
+ /* Read the partition contents (no need to retry when locked). */
+ if ((rc = hunt_nvram_read_tlv_partition(enp, partn,
+ partn_data, partn_size)) != 0) {
+ /* Failed to obtain consistent partition data */
+ goto fail4;
+ }
+
+ /* Update the contents in memory */
+ if ((rc = hunt_nvram_buf_write_tlv(partn_data, partn_size,
+ tag, data, size, &total_length)) != 0)
+ goto fail5;
+
+ /* Erase the whole partition */
+ if ((rc = hunt_nvram_partn_erase(enp, partn, 0, partn_size)) != 0)
+ goto fail6;
+
+ /* Write new partition contents to NVRAM */
+ if ((rc = hunt_nvram_partn_write(enp, partn, 0, partn_data,
+ total_length)) != 0)
+ goto fail7;
+
+ /* Unlock the partition */
+ hunt_nvram_partn_unlock(enp, partn);
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
+
+ return (0);
+
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+
+ hunt_nvram_partn_unlock(enp, partn);
+fail3:
+ EFSYS_PROBE(fail3);
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_size(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __out size_t *sizep)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_nvram_info(enp, partn, sizep, NULL, NULL)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_lock(
+ __in efx_nic_t *enp,
+ __in unsigned int partn)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_nvram_update_start(enp, partn)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_read(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ size_t chunk;
+ int rc;
+
+ while (size > 0) {
+ chunk = MIN(size, HUNTINGTON_NVRAM_CHUNK);
+
+ if ((rc = efx_mcdi_nvram_read(enp, partn, offset,
+ data, chunk)) != 0) {
+ goto fail1;
+ }
+
+ size -= chunk;
+ data += chunk;
+ offset += chunk;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_erase(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __in size_t size)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_nvram_erase(enp, partn, offset, size)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_write(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ size_t chunk;
+ int rc;
+
+ while (size > 0) {
+ chunk = MIN(size, HUNTINGTON_NVRAM_CHUNK);
+
+ if ((rc = efx_mcdi_nvram_write(enp, partn, offset,
+ data, chunk)) != 0) {
+ goto fail1;
+ }
+
+ size -= chunk;
+ data += chunk;
+ offset += chunk;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_nvram_partn_unlock(
+ __in efx_nic_t *enp,
+ __in unsigned int partn)
+{
+ boolean_t reboot;
+ int rc;
+
+ reboot = B_FALSE;
+ if ((rc = efx_mcdi_nvram_update_finish(enp, partn, reboot)) != 0)
+ goto fail1;
+
+ return;
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_set_version(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in_ecount(4) uint16_t version[4])
+{
+ struct tlv_partition_version partn_version;
+ size_t size;
+ int rc;
+
+ /* Add or modify partition version TLV item */
+ partn_version.version_w = __CPU_TO_LE_16(version[0]);
+ partn_version.version_x = __CPU_TO_LE_16(version[1]);
+ partn_version.version_y = __CPU_TO_LE_16(version[2]);
+ partn_version.version_z = __CPU_TO_LE_16(version[3]);
+
+ size = sizeof (partn_version) - (2 * sizeof (uint32_t));
+
+ if ((rc = hunt_nvram_partn_write_tlv(enp,
+ NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
+ TLV_TAG_PARTITION_VERSION(partn),
+ (caddr_t)&partn_version.version_w, size)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
+
+#if EFSYS_OPT_NVRAM
+
+typedef struct hunt_parttbl_entry_s {
+ unsigned int partn;
+ unsigned int port;
+ efx_nvram_type_t nvtype;
+} hunt_parttbl_entry_t;
+
+/* Translate EFX NVRAM types to firmware partition types */
+static hunt_parttbl_entry_t hunt_parttbl[] = {
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE, 1, EFX_NVRAM_MC_FIRMWARE},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE, 2, EFX_NVRAM_MC_FIRMWARE},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE, 3, EFX_NVRAM_MC_FIRMWARE},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE, 4, EFX_NVRAM_MC_FIRMWARE},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 1, EFX_NVRAM_MC_GOLDEN},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 2, EFX_NVRAM_MC_GOLDEN},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 3, EFX_NVRAM_MC_GOLDEN},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 4, EFX_NVRAM_MC_GOLDEN},
+ {NVRAM_PARTITION_TYPE_EXPANSION_ROM, 1, EFX_NVRAM_BOOTROM},
+ {NVRAM_PARTITION_TYPE_EXPANSION_ROM, 2, EFX_NVRAM_BOOTROM},
+ {NVRAM_PARTITION_TYPE_EXPANSION_ROM, 3, EFX_NVRAM_BOOTROM},
+ {NVRAM_PARTITION_TYPE_EXPANSION_ROM, 4, EFX_NVRAM_BOOTROM},
+ {NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT0, 1, EFX_NVRAM_BOOTROM_CFG},
+ {NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1, 2, EFX_NVRAM_BOOTROM_CFG},
+ {NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2, 3, EFX_NVRAM_BOOTROM_CFG},
+ {NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3, 4, EFX_NVRAM_BOOTROM_CFG},
+ {NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 1, EFX_NVRAM_DYNAMIC_CFG},
+ {NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 2, EFX_NVRAM_DYNAMIC_CFG},
+ {NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 3, EFX_NVRAM_DYNAMIC_CFG},
+ {NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 4, EFX_NVRAM_DYNAMIC_CFG}
+};
+
+static __checkReturn hunt_parttbl_entry_t *
+hunt_parttbl_entry(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ hunt_parttbl_entry_t *entry;
+ int i;
+
+ EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
+
+ for (i = 0; i < EFX_ARRAY_SIZE(hunt_parttbl); i++) {
+ entry = &hunt_parttbl[i];
+
+ if (entry->port == emip->emi_port && entry->nvtype == type)
+ return (entry);
+ }
+
+ return (NULL);
+}
+
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+hunt_nvram_test(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ hunt_parttbl_entry_t *entry;
+ unsigned int npartns = 0;
+ uint32_t *partns = NULL;
+ size_t size;
+ int i;
+ unsigned int j;
+ int rc;
+
+ /* Find supported partitions */
+ size = MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MAXNUM * sizeof (uint32_t);
+ EFSYS_KMEM_ALLOC(enp->en_esip, size, partns);
+ if (partns == NULL) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+
+ if ((rc = efx_mcdi_nvram_partitions(enp, (caddr_t)partns, size,
+ &npartns)) != 0) {
+ goto fail2;
+ }
+
+ /*
+ * Iterate over the list of supported partition types
+ * applicable to *this* port
+ */
+ for (i = 0; i < EFX_ARRAY_SIZE(hunt_parttbl); i++) {
+ entry = &hunt_parttbl[i];
+
+ if (entry->port != emip->emi_port)
+ continue;
+
+ for (j = 0; j < npartns; j++) {
+ if (entry->partn == partns[j]) {
+ rc = efx_mcdi_nvram_test(enp, entry->partn);
+ if (rc != 0)
+ goto fail3;
+ }
+ }
+ }
+
+ EFSYS_KMEM_FREE(enp->en_esip, size, partns);
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+ EFSYS_KMEM_FREE(enp->en_esip, size, partns);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+ __checkReturn int
+hunt_nvram_size(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out size_t *sizep)
+{
+ hunt_parttbl_entry_t *entry;
+ uint32_t partn;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ partn = entry->partn;
+
+ if ((rc = hunt_nvram_partn_size(enp, partn, sizep)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ *sizep = 0;
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_get_version(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4])
+{
+ hunt_parttbl_entry_t *entry;
+ uint32_t partn;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ partn = entry->partn;
+
+ /* FIXME: get highest partn version from all ports */
+ /* FIXME: return partn description if available */
+
+ if ((rc = efx_mcdi_nvram_metadata(enp, partn, subtypep,
+ version, NULL, 0)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_rw_start(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out size_t *chunk_sizep)
+{
+ hunt_parttbl_entry_t *entry;
+ uint32_t partn;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ partn = entry->partn;
+
+ if ((rc = hunt_nvram_partn_lock(enp, partn)) != 0)
+ goto fail2;
+
+ if (chunk_sizep != NULL)
+ *chunk_sizep = HUNTINGTON_NVRAM_CHUNK;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_read_chunk(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ hunt_parttbl_entry_t *entry;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = hunt_nvram_partn_read(enp, entry->partn,
+ offset, data, size)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_erase(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type)
+{
+ hunt_parttbl_entry_t *entry;
+ size_t size;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = hunt_nvram_partn_size(enp, entry->partn, &size)) != 0)
+ goto fail2;
+
+ if ((rc = hunt_nvram_partn_erase(enp, entry->partn, 0, size)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_write_chunk(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in unsigned int offset,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ hunt_parttbl_entry_t *entry;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = hunt_nvram_partn_write(enp, entry->partn,
+ offset, data, size)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_nvram_rw_finish(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type)
+{
+ hunt_parttbl_entry_t *entry;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) != NULL)
+ hunt_nvram_partn_unlock(enp, entry->partn);
+}
+
+ __checkReturn int
+hunt_nvram_set_version(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in_ecount(4) uint16_t version[4])
+{
+ hunt_parttbl_entry_t *entry;
+ unsigned int partn;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ partn = entry->partn;
+
+ if ((rc = hunt_nvram_partn_set_version(enp, partn, version)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_NVRAM */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_phy.c b/sys/dev/sfxge/common/hunt_phy.c
new file mode 100644
index 000000000000..1cffea21d9ff
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_phy.c
@@ -0,0 +1,701 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+static void
+hunt_phy_decode_cap(
+ __in uint32_t mcdi_cap,
+ __out uint32_t *maskp)
+{
+ /*
+ * TBD: consider common Siena/Hunt function: Hunt is a superset of
+ * Siena here (adds 40G)
+ */
+
+ uint32_t mask;
+
+ mask = 0;
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_100HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_100FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_1000HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_1000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_40000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
+ mask |= (1 << EFX_PHY_CAP_PAUSE);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
+ mask |= (1 << EFX_PHY_CAP_ASYM);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
+ mask |= (1 << EFX_PHY_CAP_AN);
+
+ *maskp = mask;
+}
+
+static void
+hunt_phy_decode_link_mode(
+ __in efx_nic_t *enp,
+ __in uint32_t link_flags,
+ __in unsigned int speed,
+ __in unsigned int fcntl,
+ __out efx_link_mode_t *link_modep,
+ __out unsigned int *fcntlp)
+{
+ /*
+ * TBD: consider common Siena/Hunt function: Hunt is a superset of
+ * Siena here (adds 40G and generate-only flow control)
+ */
+
+ boolean_t fd = !!(link_flags &
+ (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
+ boolean_t up = !!(link_flags &
+ (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
+
+ _NOTE(ARGUNUSED(enp))
+
+ if (!up)
+ *link_modep = EFX_LINK_DOWN;
+ else if (speed == 40000 && fd)
+ *link_modep = EFX_LINK_40000FDX;
+ else if (speed == 10000 && fd)
+ *link_modep = EFX_LINK_10000FDX;
+ else if (speed == 1000)
+ *link_modep = fd ? EFX_LINK_1000FDX : EFX_LINK_1000HDX;
+ else if (speed == 100)
+ *link_modep = fd ? EFX_LINK_100FDX : EFX_LINK_100HDX;
+ else if (speed == 10)
+ *link_modep = fd ? EFX_LINK_10FDX : EFX_LINK_10HDX;
+ else
+ *link_modep = EFX_LINK_UNKNOWN;
+
+ if (fcntl == MC_CMD_FCNTL_OFF)
+ *fcntlp = 0;
+ else if (fcntl == MC_CMD_FCNTL_RESPOND)
+ *fcntlp = EFX_FCNTL_RESPOND;
+ else if (fcntl == MC_CMD_FCNTL_GENERATE)
+ *fcntlp = EFX_FCNTL_GENERATE;
+ else if (fcntl == MC_CMD_FCNTL_BIDIR)
+ *fcntlp = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
+ else {
+ EFSYS_PROBE1(mc_pcol_error, int, fcntl);
+ *fcntlp = 0;
+ }
+}
+
+
+ void
+hunt_phy_link_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_link_mode_t *link_modep)
+{
+ /*
+ * TBD: consider common Siena/Hunt function: Hunt is a superset of
+ * Siena here (adds 40G)
+ */
+
+ efx_port_t *epp = &(enp->en_port);
+ unsigned int link_flags;
+ unsigned int speed;
+ unsigned int fcntl;
+ efx_link_mode_t link_mode;
+ uint32_t lp_cap_mask;
+
+ /*
+ * Convert the LINKCHANGE speed enumeration into mbit/s, in the
+ * same way as GET_LINK encodes the speed
+ */
+ switch (MCDI_EV_FIELD(eqp, LINKCHANGE_SPEED)) {
+ case MCDI_EVENT_LINKCHANGE_SPEED_100M:
+ speed = 100;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_1G:
+ speed = 1000;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_10G:
+ speed = 10000;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_40G:
+ speed = 40000;
+ break;
+ default:
+ speed = 0;
+ break;
+ }
+
+ link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS);
+ hunt_phy_decode_link_mode(enp, link_flags, speed,
+ MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL),
+ &link_mode, &fcntl);
+ hunt_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP),
+ &lp_cap_mask);
+
+ /*
+ * It's safe to update ep_lp_cap_mask without the driver's port lock
+ * because presumably any concurrently running efx_port_poll() is
+ * only going to arrive at the same value.
+ *
+ * ep_fcntl has two meanings. It's either the link common fcntl
+ * (if the PHY supports AN), or it's the forced link state. If
+ * the former, it's safe to update the value for the same reason as
+ * for ep_lp_cap_mask. If the latter, then just ignore the value,
+ * because we can race with efx_mac_fcntl_set().
+ */
+ epp->ep_lp_cap_mask = lp_cap_mask;
+ epp->ep_fcntl = fcntl;
+
+ *link_modep = link_mode;
+}
+
+ __checkReturn int
+hunt_phy_power(
+ __in efx_nic_t *enp,
+ __in boolean_t power)
+{
+ /* TBD: consider common Siena/Hunt function: essentially identical */
+
+ int rc;
+
+ if (!power)
+ return (0);
+
+ /* Check if the PHY is a zombie */
+ if ((rc = hunt_phy_verify(enp)) != 0)
+ goto fail1;
+
+ enp->en_reset_flags |= EFX_RESET_PHY;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_phy_get_link(
+ __in efx_nic_t *enp,
+ __out hunt_link_state_t *hlsp)
+{
+ /*
+ * TBD: consider common Siena/Hunt function: Hunt is very similar
+ * (at least for now; not clear that the loopbacks should necessarily
+ * be quite the same...)
+ */
+
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
+ MC_CMD_GET_LINK_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_LINK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ hunt_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP),
+ &hlsp->hls_adv_cap_mask);
+ hunt_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP),
+ &hlsp->hls_lp_cap_mask);
+
+ hunt_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS),
+ MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED),
+ MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL),
+ &hlsp->hls_link_mode, &hlsp->hls_fcntl);
+
+#if EFSYS_OPT_LOOPBACK
+ /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
+
+ hlsp->hls_loopback = MCDI_OUT_DWORD(req, GET_LINK_OUT_LOOPBACK_MODE);
+#endif /* EFSYS_OPT_LOOPBACK */
+
+ hlsp->hls_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_phy_reconfigure(
+ __in efx_nic_t *enp)
+{
+ /*
+ * TBD: this is a little different for now (no LED support for Hunt
+ * yet), but ultimately should consider common Siena/Hunt function:
+ * Hunt should be a superset of Siena here (adds 40G)
+ */
+
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_port_t *epp = &(enp->en_port);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SET_LINK_IN_LEN,
+ MC_CMD_SET_LINK_OUT_LEN)];
+ uint32_t cap_mask;
+ unsigned int led_mode;
+ unsigned int speed;
+ int rc;
+
+ if (~encp->enc_func_flags & EFX_NIC_FUNC_LINKCTRL)
+ goto out;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SET_LINK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_LINK_OUT_LEN;
+
+ cap_mask = epp->ep_adv_cap_mask;
+ MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP,
+ PHY_CAP_10HDX, (cap_mask >> EFX_PHY_CAP_10HDX) & 0x1,
+ PHY_CAP_10FDX, (cap_mask >> EFX_PHY_CAP_10FDX) & 0x1,
+ PHY_CAP_100HDX, (cap_mask >> EFX_PHY_CAP_100HDX) & 0x1,
+ PHY_CAP_100FDX, (cap_mask >> EFX_PHY_CAP_100FDX) & 0x1,
+ PHY_CAP_1000HDX, (cap_mask >> EFX_PHY_CAP_1000HDX) & 0x1,
+ PHY_CAP_1000FDX, (cap_mask >> EFX_PHY_CAP_1000FDX) & 0x1,
+ PHY_CAP_10000FDX, (cap_mask >> EFX_PHY_CAP_10000FDX) & 0x1,
+ PHY_CAP_PAUSE, (cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1,
+ PHY_CAP_ASYM, (cap_mask >> EFX_PHY_CAP_ASYM) & 0x1,
+ PHY_CAP_AN, (cap_mask >> EFX_PHY_CAP_AN) & 0x1);
+ /* Too many fields for for POPULATE macros, so insert this afterwards */
+ MCDI_IN_SET_DWORD_FIELD(req, SET_LINK_IN_CAP,
+ PHY_CAP_40000FDX, (cap_mask >> EFX_PHY_CAP_40000FDX) & 0x1);
+
+#if EFSYS_OPT_LOOPBACK
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE,
+ epp->ep_loopback_type);
+ switch (epp->ep_loopback_link_mode) {
+ case EFX_LINK_100FDX:
+ speed = 100;
+ break;
+ case EFX_LINK_1000FDX:
+ speed = 1000;
+ break;
+ case EFX_LINK_10000FDX:
+ speed = 10000;
+ break;
+ case EFX_LINK_40000FDX:
+ speed = 40000;
+ break;
+ default:
+ speed = 0;
+ }
+#else
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, MC_CMD_LOOPBACK_NONE);
+ speed = 0;
+#endif /* EFSYS_OPT_LOOPBACK */
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed);
+
+#if EFSYS_OPT_PHY_FLAGS
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags);
+#else
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0);
+#endif /* EFSYS_OPT_PHY_FLAGS */
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ /* And set the blink mode */
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SET_ID_LED;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;
+
+#if EFSYS_OPT_PHY_LED_CONTROL
+ switch (epp->ep_phy_led_mode) {
+ case EFX_PHY_LED_DEFAULT:
+ led_mode = MC_CMD_LED_DEFAULT;
+ break;
+ case EFX_PHY_LED_OFF:
+ led_mode = MC_CMD_LED_OFF;
+ break;
+ case EFX_PHY_LED_ON:
+ led_mode = MC_CMD_LED_ON;
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ led_mode = MC_CMD_LED_DEFAULT;
+ }
+
+ MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode);
+#else
+ MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT);
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+out:
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_phy_verify(
+ __in efx_nic_t *enp)
+{
+ /* TBD: consider common Siena/Hunt function: essentially identical */
+
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
+ MC_CMD_GET_PHY_STATE_OUT_LEN)];
+ uint32_t state;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PHY_STATE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_PHY_STATE_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ state = MCDI_OUT_DWORD(req, GET_PHY_STATE_OUT_STATE);
+ if (state != MC_CMD_PHY_STATE_OK) {
+ if (state != MC_CMD_PHY_STATE_ZOMBIE)
+ EFSYS_PROBE1(mc_pcol_error, int, state);
+ rc = ENOTACTIVE;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_phy_oui_get(
+ __in efx_nic_t *enp,
+ __out uint32_t *ouip)
+{
+ _NOTE(ARGUNUSED(enp, ouip))
+
+ return (ENOTSUP);
+}
+
+#if EFSYS_OPT_PHY_STATS
+
+ __checkReturn int
+hunt_phy_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_PHY_NSTATS) uint32_t *stat)
+{
+ /* TBD: no stats support in firmware yet */
+ _NOTE(ARGUNUSED(enp, esmp))
+ memset(stat, 0, EFX_PHY_NSTATS * sizeof (*stat));
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_PHY_STATS */
+
+#if EFSYS_OPT_PHY_PROPS
+
+#if EFSYS_OPT_NAMES
+
+extern const char *
+hunt_phy_prop_name(
+ __in efx_nic_t *enp,
+ __in unsigned int id)
+{
+ _NOTE(ARGUNUSED(enp, id))
+
+ return (NULL);
+}
+
+#endif /* EFSYS_OPT_NAMES */
+
+extern __checkReturn int
+hunt_phy_prop_get(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t flags,
+ __out uint32_t *valp)
+{
+ _NOTE(ARGUNUSED(enp, id, flags, valp))
+
+ return (ENOTSUP);
+}
+
+extern __checkReturn int
+hunt_phy_prop_set(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t val)
+{
+ _NOTE(ARGUNUSED(enp, id, val))
+
+ return (ENOTSUP);
+}
+
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+#if EFSYS_OPT_BIST
+
+ __checkReturn int
+hunt_bist_enable_offline(
+ __in efx_nic_t *enp)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_bist_enable_offline(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_bist_start(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_bist_start(enp, type)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_bist_poll(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
+ __out_opt __drv_when(count > 0, __notnull)
+ uint32_t *value_maskp,
+ __out_ecount_opt(count) __drv_when(count > 0, __notnull)
+ unsigned long *valuesp,
+ __in size_t count)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
+ MCDI_CTL_SDU_LEN_MAX)];
+ uint32_t value_mask = 0;
+ uint32_t result;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_POLL_BIST;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MCDI_CTL_SDU_LEN_MAX;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_POLL_BIST_OUT_RESULT_OFST + 4) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (count > 0)
+ (void) memset(valuesp, '\0', count * sizeof (unsigned long));
+
+ result = MCDI_OUT_DWORD(req, POLL_BIST_OUT_RESULT);
+
+ if (result == MC_CMD_POLL_BIST_FAILED &&
+ req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MEM_LEN &&
+ count > EFX_BIST_MEM_ECC_FATAL) {
+ if (valuesp != NULL) {
+ valuesp[EFX_BIST_MEM_TEST] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_TEST);
+ valuesp[EFX_BIST_MEM_ADDR] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ADDR);
+ valuesp[EFX_BIST_MEM_BUS] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_BUS);
+ valuesp[EFX_BIST_MEM_EXPECT] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_EXPECT);
+ valuesp[EFX_BIST_MEM_ACTUAL] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ACTUAL);
+ valuesp[EFX_BIST_MEM_ECC] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC);
+ valuesp[EFX_BIST_MEM_ECC_PARITY] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC_PARITY);
+ valuesp[EFX_BIST_MEM_ECC_FATAL] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC_FATAL);
+ }
+ value_mask |= (1 << EFX_BIST_MEM_TEST) |
+ (1 << EFX_BIST_MEM_ADDR) |
+ (1 << EFX_BIST_MEM_BUS) |
+ (1 << EFX_BIST_MEM_EXPECT) |
+ (1 << EFX_BIST_MEM_ACTUAL) |
+ (1 << EFX_BIST_MEM_ECC) |
+ (1 << EFX_BIST_MEM_ECC_PARITY) |
+ (1 << EFX_BIST_MEM_ECC_FATAL);
+ } else if (result == MC_CMD_POLL_BIST_FAILED &&
+ encp->enc_phy_type == EFX_PHY_XFI_FARMI &&
+ req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN &&
+ count > EFX_BIST_FAULT_CODE) {
+ if (valuesp != NULL)
+ valuesp[EFX_BIST_FAULT_CODE] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST);
+ value_mask |= 1 << EFX_BIST_FAULT_CODE;
+ }
+
+ if (value_maskp != NULL)
+ *value_maskp = value_mask;
+
+ EFSYS_ASSERT(resultp != NULL);
+ if (result == MC_CMD_POLL_BIST_RUNNING)
+ *resultp = EFX_BIST_RESULT_RUNNING;
+ else if (result == MC_CMD_POLL_BIST_PASSED)
+ *resultp = EFX_BIST_RESULT_PASSED;
+ else
+ *resultp = EFX_BIST_RESULT_FAILED;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_bist_stop(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type)
+{
+ /* There is no way to stop BIST on Huntinton. */
+ _NOTE(ARGUNUSED(enp, type))
+}
+
+#endif /* EFSYS_OPT_BIST */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_rx.c b/sys/dev/sfxge/common/hunt_rx.c
new file mode 100644
index 000000000000..991f29300b06
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_rx.c
@@ -0,0 +1,765 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+
+static __checkReturn int
+efx_mcdi_init_rxq(
+ __in efx_nic_t *enp,
+ __in uint32_t size,
+ __in uint32_t target_evq,
+ __in uint32_t label,
+ __in uint32_t instance,
+ __in efsys_mem_t *esmp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[
+ MAX(MC_CMD_INIT_RXQ_IN_LEN(EFX_RXQ_NBUFS(EFX_RXQ_MAXNDESCS)),
+ MC_CMD_INIT_RXQ_OUT_LEN)];
+ int npages = EFX_RXQ_NBUFS(size);
+ int i;
+ efx_qword_t *dma_addr;
+ uint64_t addr;
+ int rc;
+
+ EFSYS_ASSERT3U(size, <=, EFX_RXQ_MAXNDESCS);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_INIT_RXQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_INIT_RXQ_IN_LEN(npages);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_INIT_RXQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_SIZE, size);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_TARGET_EVQ, target_evq);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_LABEL, label);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_INSTANCE, instance);
+ MCDI_IN_POPULATE_DWORD_5(req, INIT_RXQ_IN_FLAGS,
+ INIT_RXQ_IN_FLAG_BUFF_MODE, 0,
+ INIT_RXQ_IN_FLAG_HDR_SPLIT, 0,
+ INIT_RXQ_IN_FLAG_TIMESTAMP, 0,
+ INIT_RXQ_IN_CRC_MODE, 0,
+ INIT_RXQ_IN_FLAG_PREFIX, 1);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_OWNER_ID, 0);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
+
+ dma_addr = MCDI_IN2(req, efx_qword_t, INIT_RXQ_IN_DMA_ADDR);
+ addr = EFSYS_MEM_ADDR(esmp);
+
+ for (i = 0; i < npages; i++) {
+ EFX_POPULATE_QWORD_2(*dma_addr,
+ EFX_DWORD_1, (uint32_t)(addr >> 32),
+ EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
+
+ dma_addr++;
+ addr += EFX_BUF_SIZE;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_fini_rxq(
+ __in efx_nic_t *enp,
+ __in uint32_t instance)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FINI_RXQ_IN_LEN,
+ MC_CMD_FINI_RXQ_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FINI_RXQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FINI_RXQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FINI_RXQ_IN_INSTANCE, instance);
+
+ efx_mcdi_execute(enp, &req);
+
+ if ((req.emr_rc != 0) && (req.emr_rc != MC_CMD_ERR_EALREADY)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#if EFSYS_OPT_RX_SCALE
+static __checkReturn int
+efx_mcdi_rss_context_alloc(
+ __in efx_nic_t *enp,
+ __out uint32_t *rss_contextp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
+ MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)];
+ uint32_t rss_context;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID,
+ EVB_PORT_ID_ASSIGNED);
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_TYPE,
+ MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE);
+ /* NUM_QUEUES is only used to validate indirection table offsets */
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, 64);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ rss_context = MCDI_OUT_DWORD(req, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID);
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ *rss_contextp = rss_context;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+static int
+efx_mcdi_rss_context_free(
+ __in efx_nic_t *enp,
+ __in uint32_t rss_context)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
+ MC_CMD_RSS_CONTEXT_FREE_OUT_LEN)];
+ int rc;
+
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_FREE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_FREE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_FREE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID, rss_context);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+static int
+efx_mcdi_rss_context_set_flags(
+ __in efx_nic_t *enp,
+ __in uint32_t rss_context,
+ __in efx_rx_hash_type_t type)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)];
+ int rc;
+
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_FLAGS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,
+ rss_context);
+
+ MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
+ RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,
+ (type & (1U << EFX_RX_HASH_IPV4)) ? 1 : 0,
+ RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN,
+ (type & (1U << EFX_RX_HASH_TCPIPV4)) ? 1 : 0,
+ RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN,
+ (type & (1U << EFX_RX_HASH_IPV6)) ? 1 : 0,
+ RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,
+ (type & (1U << EFX_RX_HASH_TCPIPV6)) ? 1 : 0);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+static int
+efx_mcdi_rss_context_set_key(
+ __in efx_nic_t *enp,
+ __in uint32_t rss_context,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN)];
+ int rc;
+
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_KEY;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID,
+ rss_context);
+
+ EFSYS_ASSERT3U(n, ==, MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
+ if (n != MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ memcpy(MCDI_IN2(req, uint8_t, RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY),
+ key, n);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+static int
+efx_mcdi_rss_context_set_table(
+ __in efx_nic_t *enp,
+ __in uint32_t rss_context,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN)];
+ uint8_t *req_table;
+ int i, rc;
+
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_TABLE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID,
+ rss_context);
+
+ req_table =
+ MCDI_IN2(req, uint8_t, RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE);
+
+ for (i = 0;
+ i < MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN;
+ i++) {
+ req_table[i] = (n > 0) ? (uint8_t)table[i % n] : 0;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+
+ __checkReturn int
+hunt_rx_init(
+ __in efx_nic_t *enp)
+{
+#if EFSYS_OPT_RX_SCALE
+
+ if (efx_mcdi_rss_context_alloc(enp, &enp->en_rss_context) == 0) {
+ /*
+ * Allocated an exclusive RSS context, which allows both the
+ * indirection table and key to be modified.
+ */
+ enp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;
+ enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
+ } else {
+ /*
+ * Failed to allocate an exclusive RSS context. Continue
+ * operation without support for RSS. The pseudo-header in
+ * received packets will not contain a Toeplitz hash value.
+ */
+ enp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;
+ enp->en_hash_support = EFX_RX_HASH_UNAVAILABLE;
+ }
+
+#endif /* EFSYS_OPT_RX_SCALE */
+
+ return (0);
+}
+
+#if EFSYS_OPT_RX_HDR_SPLIT
+ __checkReturn int
+hunt_rx_hdr_split_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int hdr_buf_size,
+ __in unsigned int pld_buf_size)
+{
+ int rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(enp, hdr_buf_size, pld_buf_size))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+#if EFSYS_OPT_RX_SCATTER
+ __checkReturn int
+hunt_rx_scatter_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int buf_size)
+{
+ _NOTE(ARGUNUSED(enp, buf_size))
+ return (0);
+}
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+hunt_rx_scale_mode_set(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t alg,
+ __in efx_rx_hash_type_t type,
+ __in boolean_t insert)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(alg, ==, EFX_RX_HASHALG_TOEPLITZ);
+ EFSYS_ASSERT3U(insert, ==, B_TRUE);
+
+ if ((alg != EFX_RX_HASHALG_TOEPLITZ) || (insert == B_FALSE)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+
+ if ((rc = efx_mcdi_rss_context_set_flags(enp,
+ enp->en_rss_context, type)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+hunt_rx_scale_key_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n)
+{
+ int rc;
+
+ if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = efx_mcdi_rss_context_set_key(enp,
+ enp->en_rss_context, key, n)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+hunt_rx_scale_tbl_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n)
+{
+ int rc;
+
+ if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = efx_mcdi_rss_context_set_table(enp,
+ enp->en_rss_context, table, n)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+ void
+hunt_rx_qpost(
+ __in efx_rxq_t *erp,
+ __in_ecount(n) efsys_dma_addr_t *addrp,
+ __in size_t size,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __in unsigned int added)
+{
+ efx_qword_t qword;
+ unsigned int i;
+ unsigned int offset;
+ unsigned int id;
+
+ /* The client driver must not overfill the queue */
+ EFSYS_ASSERT3U(added - completed + n, <=,
+ EFX_RXQ_LIMIT(erp->er_mask + 1));
+
+ id = added & (erp->er_mask);
+ for (i = 0; i < n; i++) {
+ EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
+ unsigned int, id, efsys_dma_addr_t, addrp[i],
+ size_t, size);
+
+ EFX_POPULATE_QWORD_3(qword,
+ ESF_DZ_RX_KER_BYTE_CNT, (uint32_t)(size),
+ ESF_DZ_RX_KER_BUF_ADDR_DW0,
+ (uint32_t)(addrp[i] & 0xffffffff),
+ ESF_DZ_RX_KER_BUF_ADDR_DW1,
+ (uint32_t)(addrp[i] >> 32));
+
+ offset = id * sizeof (efx_qword_t);
+ EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
+
+ id = (id + 1) & (erp->er_mask);
+ }
+}
+
+ void
+hunt_rx_qpush(
+ __in efx_rxq_t *erp,
+ __in unsigned int added,
+ __inout unsigned int *pushedp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ unsigned int pushed = *pushedp;
+ uint32_t wptr;
+ efx_dword_t dword;
+
+ /* Hardware has alignment restriction for WPTR */
+ wptr = P2ALIGN(added, HUNTINGTON_RX_WPTR_ALIGN);
+ if (pushed == wptr)
+ return;
+
+ *pushedp = wptr;
+
+ /* Push the populated descriptors out */
+ wptr &= erp->er_mask;
+
+ EFX_POPULATE_DWORD_1(dword, ERF_DZ_RX_DESC_WPTR, wptr);
+
+ /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
+ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
+ wptr, pushed & erp->er_mask);
+ EFSYS_PIO_WRITE_BARRIER();
+ EFX_BAR_TBL_WRITED(enp, ER_DZ_RX_DESC_UPD_REG,
+ erp->er_index, &dword, B_FALSE);
+}
+
+ __checkReturn int
+hunt_rx_qflush(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ int rc;
+
+ if ((rc = efx_mcdi_fini_rxq(enp, erp->er_index)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_rx_qenable(
+ __in efx_rxq_t *erp)
+{
+ /* FIXME */
+ _NOTE(ARGUNUSED(erp))
+ /* FIXME */
+}
+
+ __checkReturn int
+hunt_rx_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in unsigned int label,
+ __in efx_rxq_type_t type,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in efx_evq_t *eep,
+ __in efx_rxq_t *erp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ int rc;
+
+ _NOTE(ARGUNUSED(erp))
+
+ EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS == (1 << ESF_DZ_RX_QLABEL_WIDTH));
+ EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
+ EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
+
+ EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
+ EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
+
+ if (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+ if (index >= encp->enc_rxq_limit) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ /*
+ * FIXME: Siena code handles different queue types (default, header
+ * split, scatter); we'll need to do something more here later, but
+ * all that stuff is TBD for now.
+ */
+
+ if ((rc = efx_mcdi_init_rxq(enp, n, eep->ee_index, label, index,
+ esmp)) != 0)
+ goto fail3;
+
+ erp->er_eep = eep;
+ erp->er_label = label;
+
+ hunt_ev_rxlabel_init(eep, erp, label);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_rx_qdestroy(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_evq_t *eep = erp->er_eep;
+ unsigned int label = erp->er_label;
+
+ hunt_ev_rxlabel_fini(eep, label);
+
+ EFSYS_ASSERT(enp->en_rx_qcount != 0);
+ --enp->en_rx_qcount;
+
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
+}
+
+ void
+hunt_rx_fini(
+ __in efx_nic_t *enp)
+{
+#if EFSYS_OPT_RX_SCALE
+ if (enp->en_rss_support != EFX_RX_SCALE_UNAVAILABLE) {
+ (void) efx_mcdi_rss_context_free(enp, enp->en_rss_context);
+ }
+ enp->en_rss_context = 0;
+ enp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;
+#else
+ _NOTE(ARGUNUSED(enp))
+#endif /* EFSYS_OPT_RX_SCALE */
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_sram.c b/sys/dev/sfxge/common/hunt_sram.c
new file mode 100644
index 000000000000..947e033ef7e6
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_sram.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+hunt_sram_test(
+ __in efx_nic_t *enp,
+ __in efx_sram_pattern_fn_t func)
+{
+ int rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(enp))
+ _NOTE(ARGUNUSED(func))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_tx.c b/sys/dev/sfxge/common/hunt_tx.c
new file mode 100755
index 000000000000..ee5691ac49db
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_tx.c
@@ -0,0 +1,679 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_QSTATS
+#define EFX_TX_QSTAT_INCR(_etp, _stat) \
+ do { \
+ (_etp)->et_stat[_stat]++; \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+#else
+#define EFX_TX_QSTAT_INCR(_etp, _stat)
+#endif
+
+static __checkReturn int
+efx_mcdi_init_txq(
+ __in efx_nic_t *enp,
+ __in uint32_t size,
+ __in uint32_t target_evq,
+ __in uint32_t label,
+ __in uint32_t instance,
+ __in uint16_t flags,
+ __in efsys_mem_t *esmp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_INIT_TXQ_IN_LEN(EFX_TXQ_MAX_BUFS),
+ MC_CMD_INIT_TXQ_OUT_LEN)];
+ efx_qword_t *dma_addr;
+ uint64_t addr;
+ int npages;
+ int i;
+ int rc;
+
+ EFSYS_ASSERT(EFX_TXQ_MAX_BUFS >=
+ EFX_TXQ_NBUFS(EFX_TXQ_MAXNDESCS(&enp->en_nic_cfg)));
+
+ npages = EFX_TXQ_NBUFS(size);
+ if (npages > MC_CMD_INIT_TXQ_IN_DMA_ADDR_MAXNUM) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_INIT_TXQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_INIT_TXQ_IN_LEN(npages);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_INIT_TXQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_SIZE, size);
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_TARGET_EVQ, target_evq);
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_LABEL, label);
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_INSTANCE, instance);
+
+ MCDI_IN_POPULATE_DWORD_6(req, INIT_TXQ_IN_FLAGS,
+ INIT_TXQ_IN_FLAG_BUFF_MODE, 0,
+ INIT_TXQ_IN_FLAG_IP_CSUM_DIS, (flags & EFX_CKSUM_IPV4) ? 0 : 1,
+ INIT_TXQ_IN_FLAG_TCP_CSUM_DIS, (flags & EFX_CKSUM_TCPUDP) ? 0 : 1,
+ INIT_TXQ_IN_FLAG_TCP_UDP_ONLY, 0,
+ INIT_TXQ_IN_CRC_MODE, 0,
+ INIT_TXQ_IN_FLAG_TIMESTAMP, 0);
+
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_OWNER_ID, 0);
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
+
+ dma_addr = MCDI_IN2(req, efx_qword_t, INIT_TXQ_IN_DMA_ADDR);
+ addr = EFSYS_MEM_ADDR(esmp);
+
+ for (i = 0; i < npages; i++) {
+ EFX_POPULATE_QWORD_2(*dma_addr,
+ EFX_DWORD_1, (uint32_t)(addr >> 32),
+ EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
+
+ dma_addr++;
+ addr += EFX_BUF_SIZE;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_fini_txq(
+ __in efx_nic_t *enp,
+ __in uint32_t instance)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FINI_TXQ_IN_LEN,
+ MC_CMD_FINI_TXQ_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FINI_TXQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FINI_TXQ_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FINI_TXQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FINI_TXQ_IN_INSTANCE, instance);
+
+ efx_mcdi_execute(enp, &req);
+
+ if ((req.emr_rc != 0) && (req.emr_rc != MC_CMD_ERR_EALREADY)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_tx_init(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+ return (0);
+}
+
+ void
+hunt_tx_fini(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+ __checkReturn int
+hunt_tx_qcreate(
+ __in efx_nic_t *enp,
+ __in unsigned int index,
+ __in unsigned int label,
+ __in efsys_mem_t *esmp,
+ __in size_t n,
+ __in uint32_t id,
+ __in uint16_t flags,
+ __in efx_evq_t *eep,
+ __in efx_txq_t *etp,
+ __out unsigned int *addedp)
+{
+ efx_qword_t desc;
+ int rc;
+
+
+ if ((rc = efx_mcdi_init_txq(enp, n, eep->ee_index, label, index, flags,
+ esmp)) != 0)
+ goto fail1;
+
+ /*
+ * A previous user of this TX queue may have written a descriptor to the
+ * TX push collector, but not pushed the doorbell (e.g. after a crash).
+ * The next doorbell write would then push the stale descriptor.
+ *
+ * Ensure the (per network port) TX push collector is cleared by writing
+ * a no-op TX option descriptor. See bug29981 for details.
+ */
+ *addedp = 1;
+ EFX_POPULATE_QWORD_4(desc,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE, ESE_DZ_TX_OPTION_DESC_CRC_CSUM,
+ ESF_DZ_TX_OPTION_UDP_TCP_CSUM, (flags & EFX_CKSUM_TCPUDP) ? 1 : 0,
+ ESF_DZ_TX_OPTION_IP_CSUM, (flags & EFX_CKSUM_IPV4) ? 1 : 0);
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, 0, &desc);
+ hunt_tx_qpush(etp, *addedp, 0);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_tx_qdestroy(
+ __in efx_txq_t *etp)
+{
+ /* FIXME */
+ _NOTE(ARGUNUSED(etp))
+ /* FIXME */
+}
+
+ __checkReturn int
+hunt_tx_qpio_enable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_piobuf_handle_t handle;
+ int rc;
+
+ if (etp->et_pio_size != 0) {
+ rc = EALREADY;
+ goto fail1;
+ }
+
+ /* Sub-allocate a PIO block from a piobuf */
+ if ((rc = hunt_nic_pio_alloc(enp,
+ &etp->et_pio_bufnum,
+ &handle,
+ &etp->et_pio_blknum,
+ &etp->et_pio_offset,
+ &etp->et_pio_size)) != 0) {
+ goto fail2;
+ }
+ EFSYS_ASSERT3U(etp->et_pio_size, !=, 0);
+
+ /* Link the piobuf to this TXQ */
+ if ((rc = hunt_nic_pio_link(enp, etp->et_index, handle)) != 0) {
+ goto fail3;
+ }
+
+ /*
+ * et_pio_offset is the offset of the sub-allocated block within the
+ * hardware PIO buffer. It is used as the buffer address in the PIO
+ * option descriptor.
+ *
+ * et_pio_write_offset is the offset of the sub-allocated block from the
+ * start of the write-combined memory mapping, and is used for writing
+ * data into the PIO buffer.
+ */
+ etp->et_pio_write_offset =
+ (etp->et_pio_bufnum * ER_DZ_TX_PIOBUF_STEP) +
+ ER_DZ_TX_PIOBUF_OFST + etp->et_pio_offset;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+ hunt_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
+ etp->et_pio_size = 0;
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_tx_qpio_disable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+
+ if (etp->et_pio_size != 0) {
+ /* Unlink the piobuf from this TXQ */
+ hunt_nic_pio_unlink(enp, etp->et_index);
+
+ /* Free the sub-allocated PIO block */
+ hunt_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
+ etp->et_pio_size = 0;
+ etp->et_pio_write_offset = 0;
+ }
+}
+
+ __checkReturn int
+hunt_tx_qpio_write(
+ __in efx_txq_t *etp,
+ __in_ecount(length) uint8_t *buffer,
+ __in size_t length,
+ __in size_t offset)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efsys_bar_t *esbp = enp->en_esbp;
+ uint32_t write_offset;
+ uint32_t write_offset_limit;
+ efx_qword_t *eqp;
+ int rc;
+
+ EFSYS_ASSERT(length % sizeof (efx_qword_t) == 0);
+
+ if (etp->et_pio_size == 0) {
+ rc = ENOENT;
+ goto fail1;
+ }
+ if (offset + length > etp->et_pio_size) {
+ rc = ENOSPC;
+ goto fail2;
+ }
+
+ /*
+ * Writes to PIO buffers must be 64 bit aligned, and multiples of
+ * 64 bits.
+ */
+ write_offset = etp->et_pio_write_offset + offset;
+ write_offset_limit = write_offset + length;
+ eqp = (efx_qword_t *)buffer;
+ while (write_offset < write_offset_limit) {
+ EFSYS_BAR_WC_WRITEQ(esbp, write_offset, eqp);
+ eqp++;
+ write_offset += sizeof (efx_qword_t);
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_tx_qpio_post(
+ __in efx_txq_t *etp,
+ __in size_t pkt_length,
+ __in unsigned int completed,
+ __inout unsigned int *addedp)
+{
+ efx_qword_t pio_desc;
+ unsigned int id;
+ size_t offset;
+ unsigned int added = *addedp;
+ int rc;
+
+
+ if (added - completed + 1 > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ if (etp->et_pio_size == 0) {
+ rc = ENOENT;
+ goto fail2;
+ }
+
+ id = added++ & etp->et_mask;
+ offset = id * sizeof (efx_qword_t);
+
+ EFSYS_PROBE4(tx_pio_post, unsigned int, etp->et_index,
+ unsigned int, id, uint32_t, etp->et_pio_offset,
+ size_t, pkt_length);
+
+ EFX_POPULATE_QWORD_5(pio_desc,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE, 1,
+ ESF_DZ_TX_PIO_CONT, 0,
+ ESF_DZ_TX_PIO_BYTE_CNT, pkt_length,
+ ESF_DZ_TX_PIO_BUF_ADDR, etp->et_pio_offset);
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &pio_desc);
+
+ EFX_TX_QSTAT_INCR(etp, TX_POST_PIO);
+
+ *addedp = added;
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_tx_qpost(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_buffer_t *eb,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp)
+{
+ unsigned int added = *addedp;
+ unsigned int i;
+ int rc;
+
+ if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ for (i = 0; i < n; i++) {
+ efx_buffer_t *ebp = &eb[i];
+ efsys_dma_addr_t addr = ebp->eb_addr;
+ size_t size = ebp->eb_size;
+ boolean_t eop = ebp->eb_eop;
+ unsigned int id;
+ size_t offset;
+ efx_qword_t qword;
+
+ /* Fragments must not span 4k boundaries. */
+ EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= (addr + size));
+
+ id = added++ & etp->et_mask;
+ offset = id * sizeof (efx_qword_t);
+
+ EFSYS_PROBE5(tx_post, unsigned int, etp->et_index,
+ unsigned int, id, efsys_dma_addr_t, addr,
+ size_t, size, boolean_t, eop);
+
+ EFX_POPULATE_QWORD_5(qword,
+ ESF_DZ_TX_KER_TYPE, 0,
+ ESF_DZ_TX_KER_CONT, (eop) ? 0 : 1,
+ ESF_DZ_TX_KER_BYTE_CNT, (uint32_t)(size),
+ ESF_DZ_TX_KER_BUF_ADDR_DW0, (uint32_t)(addr & 0xffffffff),
+ ESF_DZ_TX_KER_BUF_ADDR_DW1, (uint32_t)(addr >> 32));
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &qword);
+ }
+
+ EFX_TX_QSTAT_INCR(etp, TX_POST);
+
+ *addedp = added;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * This improves performance by pushing a TX descriptor at the same time as the
+ * doorbell. The descriptor must be added to the TXQ, so that can be used if the
+ * hardware decides not to use the pushed descriptor.
+ */
+ void
+hunt_tx_qpush(
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed)
+{
+ efx_nic_t *enp = etp->et_enp;
+ unsigned int wptr;
+ unsigned int id;
+ size_t offset;
+ efx_qword_t desc;
+ efx_oword_t oword;
+
+ wptr = added & etp->et_mask;
+ id = pushed & etp->et_mask;
+ offset = id * sizeof (efx_qword_t);
+
+ EFSYS_MEM_READQ(etp->et_esmp, offset, &desc);
+ EFX_POPULATE_OWORD_3(oword,
+ ERF_DZ_TX_DESC_WPTR, wptr,
+ ERF_DZ_TX_DESC_HWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_1),
+ ERF_DZ_TX_DESC_LWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_0));
+
+ /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
+ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1, wptr, id);
+ EFSYS_PIO_WRITE_BARRIER();
+ EFX_BAR_TBL_DOORBELL_WRITEO(enp, ER_DZ_TX_DESC_UPD_REG, etp->et_index,
+ &oword);
+}
+
+ __checkReturn int
+hunt_tx_qdesc_post(
+ __in efx_txq_t *etp,
+ __in_ecount(n) efx_desc_t *ed,
+ __in unsigned int n,
+ __in unsigned int completed,
+ __inout unsigned int *addedp)
+{
+ unsigned int added = *addedp;
+ unsigned int i;
+ int rc;
+
+ if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ for (i = 0; i < n; i++) {
+ efx_desc_t *edp = &ed[i];
+ unsigned int id;
+ size_t offset;
+
+ id = added++ & etp->et_mask;
+ offset = id * sizeof (efx_desc_t);
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
+ }
+
+ EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
+ unsigned int, added, unsigned int, n);
+
+ EFX_TX_QSTAT_INCR(etp, TX_POST);
+
+ *addedp = added;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_tx_qdesc_dma_create(
+ __in efx_txq_t *etp,
+ __in efsys_dma_addr_t addr,
+ __in size_t size,
+ __in boolean_t eop,
+ __out efx_desc_t *edp)
+{
+ /* Fragments must not span 4k boundaries. */
+ EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
+
+ EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
+ efsys_dma_addr_t, addr,
+ size_t, size, boolean_t, eop);
+
+ EFX_POPULATE_QWORD_5(edp->ed_eq,
+ ESF_DZ_TX_KER_TYPE, 0,
+ ESF_DZ_TX_KER_CONT, (eop) ? 0 : 1,
+ ESF_DZ_TX_KER_BYTE_CNT, (uint32_t)(size),
+ ESF_DZ_TX_KER_BUF_ADDR_DW0, (uint32_t)(addr & 0xffffffff),
+ ESF_DZ_TX_KER_BUF_ADDR_DW1, (uint32_t)(addr >> 32));
+}
+
+ void
+hunt_tx_qdesc_tso_create(
+ __in efx_txq_t *etp,
+ __in uint16_t ipv4_id,
+ __in uint32_t tcp_seq,
+ __in uint8_t tcp_flags,
+ __out efx_desc_t *edp)
+{
+ EFSYS_PROBE4(tx_desc_tso_create, unsigned int, etp->et_index,
+ uint16_t, ipv4_id, uint32_t, tcp_seq,
+ uint8_t, tcp_flags);
+
+ EFX_POPULATE_QWORD_5(edp->ed_eq,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE,
+ ESE_DZ_TX_OPTION_DESC_TSO,
+ ESF_DZ_TX_TSO_TCP_FLAGS, tcp_flags,
+ ESF_DZ_TX_TSO_IP_ID, ipv4_id,
+ ESF_DZ_TX_TSO_TCP_SEQNO, tcp_seq);
+}
+
+ void
+hunt_tx_qdesc_vlantci_create(
+ __in efx_txq_t *etp,
+ __in uint16_t tci,
+ __out efx_desc_t *edp)
+{
+ EFSYS_PROBE2(tx_desc_vlantci_create, unsigned int, etp->et_index,
+ uint16_t, tci);
+
+ EFX_POPULATE_QWORD_4(edp->ed_eq,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE,
+ ESE_DZ_TX_OPTION_DESC_VLAN,
+ ESF_DZ_TX_VLAN_OP, tci ? 1 : 0,
+ ESF_DZ_TX_VLAN_TAG1, tci);
+}
+
+
+ __checkReturn int
+hunt_tx_qpace(
+ __in efx_txq_t *etp,
+ __in unsigned int ns)
+{
+ int rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(etp, ns))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_tx_qflush(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ int rc;
+
+ if ((rc = efx_mcdi_fini_txq(enp, etp->et_index)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_tx_qenable(
+ __in efx_txq_t *etp)
+{
+ /* FIXME */
+ _NOTE(ARGUNUSED(etp))
+ /* FIXME */
+}
+
+#if EFSYS_OPT_QSTATS
+ void
+hunt_tx_qstats_update(
+ __in efx_txq_t *etp,
+ __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+
+ unsigned int id;
+
+ for (id = 0; id < TX_NQSTATS; id++) {
+ efsys_stat_t *essp = &stat[id];
+
+ EFSYS_STAT_INCR(essp, etp->et_stat[id]);
+ etp->et_stat[id] = 0;
+ }
+}
+
+#endif /* EFSYS_OPT_QSTATS */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_vpd.c b/sys/dev/sfxge/common/hunt_vpd.c
new file mode 100644
index 000000000000..536ebbcf06f3
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_vpd.c
@@ -0,0 +1,435 @@
+/*-
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_regs.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_VPD
+
+#if EFSYS_OPT_HUNTINGTON
+
+#include "ef10_tlv_layout.h"
+
+ __checkReturn int
+hunt_vpd_init(
+ __in efx_nic_t *enp)
+{
+ caddr_t svpd;
+ size_t svpd_size;
+ uint32_t pci_pf;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ pci_pf = enp->en_nic_cfg.enc_pf;
+ /*
+ * The VPD interface exposes VPD resources from the combined static and
+ * dynamic VPD storage. As the static VPD configuration should *never*
+ * change, we can cache it.
+ */
+ svpd = NULL;
+ svpd_size = 0;
+ rc = hunt_nvram_partn_read_tlv(enp,
+ NVRAM_PARTITION_TYPE_STATIC_CONFIG,
+ TLV_TAG_PF_STATIC_VPD(pci_pf),
+ &svpd, &svpd_size);
+ if (rc != 0) {
+ if (rc == EACCES) {
+ /* Unpriviledged functions cannot access VPD */
+ goto out;
+ }
+ goto fail1;
+ }
+
+ if (svpd != NULL && svpd_size > 0) {
+ if ((rc = efx_vpd_hunk_verify(svpd, svpd_size, NULL)) != 0)
+ goto fail2;
+ }
+
+ enp->en_u.hunt.enu_svpd = svpd;
+ enp->en_u.hunt.enu_svpd_length = svpd_size;
+
+out:
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+ EFSYS_KMEM_FREE(enp->en_esip, svpd_size, svpd);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_size(
+ __in efx_nic_t *enp,
+ __out size_t *sizep)
+{
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * This function returns the total size the user should allocate
+ * for all VPD operations. We've already cached the static vpd,
+ * so we just need to return an upper bound on the dynamic vpd,
+ * which is the size of the DYNAMIC_CONFIG partition.
+ */
+ if ((rc = efx_mcdi_nvram_info(enp, NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
+ sizep, NULL, NULL)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_read(
+ __in efx_nic_t *enp,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ caddr_t dvpd;
+ size_t dvpd_size;
+ uint32_t pci_pf;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ pci_pf = enp->en_nic_cfg.enc_pf;
+
+ if ((rc = hunt_nvram_partn_read_tlv(enp,
+ NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
+ TLV_TAG_PF_DYNAMIC_VPD(pci_pf),
+ &dvpd, &dvpd_size)) != 0)
+ goto fail1;
+
+ if (dvpd_size > size) {
+ rc = ENOSPC;
+ goto fail2;
+ }
+ memcpy(data, dvpd, dvpd_size);
+
+ /* Pad data with all-1s, consistent with update operations */
+ memset(data + dvpd_size, 0xff, size - dvpd_size);
+
+ EFSYS_KMEM_FREE(enp->en_esip, dvpd_size, dvpd);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+ EFSYS_KMEM_FREE(enp->en_esip, dvpd_size, dvpd);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_verify(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ efx_vpd_tag_t stag;
+ efx_vpd_tag_t dtag;
+ efx_vpd_keyword_t skey;
+ efx_vpd_keyword_t dkey;
+ unsigned int scont;
+ unsigned int dcont;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * Strictly you could take the view that dynamic vpd is optional.
+ * Instead, to conform more closely to the read/verify/reinit()
+ * paradigm, we require dynamic vpd. hunt_vpd_reinit() will
+ * reinitialize it as required.
+ */
+ if ((rc = efx_vpd_hunk_verify(data, size, NULL)) != 0)
+ goto fail1;
+
+ /*
+ * Verify that there is no duplication between the static and
+ * dynamic cfg sectors.
+ */
+ if (enp->en_u.hunt.enu_svpd_length == 0)
+ goto done;
+
+ dcont = 0;
+ _NOTE(CONSTANTCONDITION)
+ while (1) {
+ if ((rc = efx_vpd_hunk_next(data, size, &dtag,
+ &dkey, NULL, NULL, &dcont)) != 0)
+ goto fail2;
+ if (dcont == 0)
+ break;
+
+ scont = 0;
+ _NOTE(CONSTANTCONDITION)
+ while (1) {
+ if ((rc = efx_vpd_hunk_next(
+ enp->en_u.hunt.enu_svpd,
+ enp->en_u.hunt.enu_svpd_length, &stag, &skey,
+ NULL, NULL, &scont)) != 0)
+ goto fail3;
+ if (scont == 0)
+ break;
+
+ if (stag == dtag && skey == dkey) {
+ rc = EEXIST;
+ goto fail4;
+ }
+ }
+ }
+
+done:
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_reinit(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ boolean_t wantpid;
+ int rc;
+
+ /*
+ * Only create an ID string if the dynamic cfg doesn't have one
+ */
+ if (enp->en_u.hunt.enu_svpd_length == 0)
+ wantpid = B_TRUE;
+ else {
+ unsigned int offset;
+ uint8_t length;
+
+ rc = efx_vpd_hunk_get(enp->en_u.hunt.enu_svpd,
+ enp->en_u.hunt.enu_svpd_length,
+ EFX_VPD_ID, 0, &offset, &length);
+ if (rc == 0)
+ wantpid = B_FALSE;
+ else if (rc == ENOENT)
+ wantpid = B_TRUE;
+ else
+ goto fail1;
+ }
+
+ if ((rc = efx_vpd_hunk_reinit(data, size, wantpid)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_get(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __inout efx_vpd_value_t *evvp)
+{
+ unsigned int offset;
+ uint8_t length;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /* Attempt to satisfy the request from svpd first */
+ if (enp->en_u.hunt.enu_svpd_length > 0) {
+ if ((rc = efx_vpd_hunk_get(enp->en_u.hunt.enu_svpd,
+ enp->en_u.hunt.enu_svpd_length, evvp->evv_tag,
+ evvp->evv_keyword, &offset, &length)) == 0) {
+ evvp->evv_length = length;
+ memcpy(evvp->evv_value,
+ enp->en_u.hunt.enu_svpd + offset, length);
+ return (0);
+ } else if (rc != ENOENT)
+ goto fail1;
+ }
+
+ /* And then from the provided data buffer */
+ if ((rc = efx_vpd_hunk_get(data, size, evvp->evv_tag,
+ evvp->evv_keyword, &offset, &length)) != 0)
+ goto fail2;
+
+ evvp->evv_length = length;
+ memcpy(evvp->evv_value, data + offset, length);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_set(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __in efx_vpd_value_t *evvp)
+{
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /* If the provided (tag,keyword) exists in svpd, then it is readonly */
+ if (enp->en_u.hunt.enu_svpd_length > 0) {
+ unsigned int offset;
+ uint8_t length;
+
+ if ((rc = efx_vpd_hunk_get(enp->en_u.hunt.enu_svpd,
+ enp->en_u.hunt.enu_svpd_length, evvp->evv_tag,
+ evvp->evv_keyword, &offset, &length)) == 0) {
+ rc = EACCES;
+ goto fail1;
+ }
+ }
+
+ if ((rc = efx_vpd_hunk_set(data, size, evvp)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_next(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __out efx_vpd_value_t *evvp,
+ __inout unsigned int *contp)
+{
+ _NOTE(ARGUNUSED(enp, data, size, evvp, contp))
+
+ return (ENOTSUP);
+}
+
+ __checkReturn int
+hunt_vpd_write(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ size_t vpd_length;
+ uint32_t pci_pf;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ pci_pf = enp->en_nic_cfg.enc_pf;
+
+ /* Determine total length of new dynamic VPD */
+ if ((rc = efx_vpd_hunk_length(data, size, &vpd_length)) != 0)
+ goto fail1;
+
+ /* Store new dynamic VPD in DYNAMIC_CONFIG partition */
+ if ((rc = hunt_nvram_partn_write_tlv(enp,
+ NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
+ TLV_TAG_PF_DYNAMIC_VPD(pci_pf),
+ data, vpd_length)) != 0) {
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_vpd_fini(
+ __in efx_nic_t *enp)
+{
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ if (enp->en_u.hunt.enu_svpd_length > 0) {
+ EFSYS_KMEM_FREE(enp->en_esip, enp->en_u.hunt.enu_svpd_length,
+ enp->en_u.hunt.enu_svpd);
+
+ enp->en_u.hunt.enu_svpd = NULL;
+ enp->en_u.hunt.enu_svpd_length = 0;
+ }
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+#endif /* EFSYS_OPT_VPD */
diff --git a/sys/dev/sfxge/common/mcdi_mon.c b/sys/dev/sfxge/common/mcdi_mon.c
new file mode 100644
index 000000000000..ec692be1e6c1
--- /dev/null
+++ b/sys/dev/sfxge/common/mcdi_mon.c
@@ -0,0 +1,552 @@
+/*-
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_MON_MCDI
+
+#if EFSYS_OPT_MON_STATS
+
+#define MCDI_MON_NEXT_PAGE (uint16_t)0xfffe
+#define MCDI_MON_INVALID_SENSOR (uint16_t)0xfffd
+#define MCDI_MON_PAGE_SIZE 0x20
+
+/* Bitmasks of valid port(s) for each sensor */
+#define MCDI_MON_PORT_NONE (0x00)
+#define MCDI_MON_PORT_P1 (0x01)
+#define MCDI_MON_PORT_P2 (0x02)
+#define MCDI_MON_PORT_P3 (0x04)
+#define MCDI_MON_PORT_P4 (0x08)
+#define MCDI_MON_PORT_Px (0xFFFF)
+
+/* Entry for MCDI sensor in sensor map */
+#define STAT(portmask, stat) \
+ { (MCDI_MON_PORT_##portmask), (EFX_MON_STAT_##stat) }
+
+/* Entry for sensor next page flag in sensor map */
+#define STAT_NEXT_PAGE() \
+ { MCDI_MON_PORT_NONE, MCDI_MON_NEXT_PAGE }
+
+/* Placeholder for gaps in the array */
+#define STAT_NO_SENSOR() \
+ { MCDI_MON_PORT_NONE, MCDI_MON_INVALID_SENSOR }
+
+/* Map from MC sensors to monitor statistics */
+static const struct mcdi_sensor_map_s {
+ uint16_t msm_port_mask;
+ uint16_t msm_stat;
+} mcdi_sensor_map[] = {
+ /* Sensor page 0 MC_CMD_SENSOR_xxx */
+ STAT(Px, INT_TEMP), /* 0x00 CONTROLLER_TEMP */
+ STAT(Px, EXT_TEMP), /* 0x01 PHY_COMMON_TEMP */
+ STAT(Px, INT_COOLING), /* 0x02 CONTROLLER_COOLING */
+ STAT(P1, EXT_TEMP), /* 0x03 PHY0_TEMP */
+ STAT(P1, EXT_COOLING), /* 0x04 PHY0_COOLING */
+ STAT(P2, EXT_TEMP), /* 0x05 PHY1_TEMP */
+ STAT(P2, EXT_COOLING), /* 0x06 PHY1_COOLING */
+ STAT(Px, 1V), /* 0x07 IN_1V0 */
+ STAT(Px, 1_2V), /* 0x08 IN_1V2 */
+ STAT(Px, 1_8V), /* 0x09 IN_1V8 */
+ STAT(Px, 2_5V), /* 0x0a IN_2V5 */
+ STAT(Px, 3_3V), /* 0x0b IN_3V3 */
+ STAT(Px, 12V), /* 0x0c IN_12V0 */
+ STAT(Px, 1_2VA), /* 0x0d IN_1V2A */
+ STAT(Px, VREF), /* 0x0e IN_VREF */
+ STAT(Px, VAOE), /* 0x0f OUT_VAOE */
+ STAT(Px, AOE_TEMP), /* 0x10 AOE_TEMP */
+ STAT(Px, PSU_AOE_TEMP), /* 0x11 PSU_AOE_TEMP */
+ STAT(Px, PSU_TEMP), /* 0x12 PSU_TEMP */
+ STAT(Px, FAN0), /* 0x13 FAN_0 */
+ STAT(Px, FAN1), /* 0x14 FAN_1 */
+ STAT(Px, FAN2), /* 0x15 FAN_2 */
+ STAT(Px, FAN3), /* 0x16 FAN_3 */
+ STAT(Px, FAN4), /* 0x17 FAN_4 */
+ STAT(Px, VAOE_IN), /* 0x18 IN_VAOE */
+ STAT(Px, IAOE), /* 0x19 OUT_IAOE */
+ STAT(Px, IAOE_IN), /* 0x1a IN_IAOE */
+ STAT(Px, NIC_POWER), /* 0x1b NIC_POWER */
+ STAT(Px, 0_9V), /* 0x1c IN_0V9 */
+ STAT(Px, I0_9V), /* 0x1d IN_I0V9 */
+ STAT(Px, I1_2V), /* 0x1e IN_I1V2 */
+ STAT_NEXT_PAGE(), /* 0x1f Next page flag (not a sensor) */
+
+ /* Sensor page 1 MC_CMD_SENSOR_xxx */
+ STAT(Px, 0_9V_ADC), /* 0x20 IN_0V9_ADC */
+ STAT(Px, INT_TEMP2), /* 0x21 CONTROLLER_2_TEMP */
+ STAT(Px, VREG_TEMP), /* 0x22 VREG_INTERNAL_TEMP */
+ STAT(Px, VREG_0_9V_TEMP), /* 0x23 VREG_0V9_TEMP */
+ STAT(Px, VREG_1_2V_TEMP), /* 0x24 VREG_1V2_TEMP */
+ STAT(Px, INT_VPTAT), /* 0x25 CTRLR. VPTAT */
+ STAT(Px, INT_ADC_TEMP), /* 0x26 CTRLR. INTERNAL_TEMP */
+ STAT(Px, EXT_VPTAT), /* 0x27 CTRLR. VPTAT_EXTADC */
+ STAT(Px, EXT_ADC_TEMP), /* 0x28 CTRLR. INTERNAL_TEMP_EXTADC */
+ STAT(Px, AMBIENT_TEMP), /* 0x29 AMBIENT_TEMP */
+ STAT(Px, AIRFLOW), /* 0x2a AIRFLOW */
+ STAT(Px, VDD08D_VSS08D_CSR), /* 0x2b VDD08D_VSS08D_CSR */
+ STAT(Px, VDD08D_VSS08D_CSR_EXTADC), /* 0x2c VDD08D_VSS08D_CSR_EXTADC */
+ STAT(Px, HOTPOINT_TEMP), /* 0x2d HOTPOINT_TEMP */
+ STAT(P1, PHY_POWER_SWITCH_PORT0), /* 0x2e PHY_POWER_SWITCH_PORT0 */
+ STAT(P2, PHY_POWER_SWITCH_PORT1), /* 0x2f PHY_POWER_SWITCH_PORT1 */
+ STAT(Px, MUM_VCC), /* 0x30 MUM_VCC */
+ STAT(Px, 0V9_A), /* 0x31 0V9_A */
+ STAT(Px, I0V9_A), /* 0x32 I0V9_A */
+ STAT(Px, 0V9_A_TEMP), /* 0x33 0V9_A_TEMP */
+ STAT(Px, 0V9_B), /* 0x34 0V9_B */
+ STAT(Px, I0V9_B), /* 0x35 I0V9_B */
+ STAT(Px, 0V9_B_TEMP), /* 0x36 0V9_B_TEMP */
+ STAT(Px, CCOM_AVREG_1V2_SUPPLY), /* 0x37 CCOM_AVREG_1V2_SUPPLY */
+ STAT(Px, CCOM_AVREG_1V2_SUPPLY_EXT_ADC),
+ /* 0x38 CCOM_AVREG_1V2_SUPPLY_EXT_ADC */
+ STAT(Px, CCOM_AVREG_1V8_SUPPLY), /* 0x39 CCOM_AVREG_1V8_SUPPLY */
+ STAT(Px, CCOM_AVREG_1V8_SUPPLY_EXT_ADC),
+ /* 0x3a CCOM_AVREG_1V8_SUPPLY_EXT_ADC */
+ STAT_NO_SENSOR(), /* 0x3b (no sensor) */
+ STAT_NO_SENSOR(), /* 0x3c (no sensor) */
+ STAT_NO_SENSOR(), /* 0x3d (no sensor) */
+ STAT_NO_SENSOR(), /* 0x3e (no sensor) */
+ STAT_NEXT_PAGE(), /* 0x3f Next page flag (not a sensor) */
+
+ /* Sensor page 2 MC_CMD_SENSOR_xxx */
+ STAT(Px, CONTROLLER_MASTER_VPTAT), /* 0x40 MASTER_VPTAT */
+ STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP), /* 0x41 MASTER_INT_TEMP */
+ STAT(Px, CONTROLLER_MASTER_VPTAT_EXT_ADC), /* 0x42 MAST_VPTAT_EXT_ADC */
+ STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC),
+ /* 0x43 MASTER_INTERNAL_TEMP_EXT_ADC */
+ STAT(Px, CONTROLLER_SLAVE_VPTAT), /* 0x44 SLAVE_VPTAT */
+ STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP), /* 0x45 SLAVE_INTERNAL_TEMP */
+ STAT(Px, CONTROLLER_SLAVE_VPTAT_EXT_ADC), /* 0x46 SLAVE_VPTAT_EXT_ADC */
+ STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC),
+ /* 0x47 SLAVE_INTERNAL_TEMP_EXT_ADC */
+};
+
+#define MCDI_STATIC_SENSOR_ASSERT(_field) \
+ EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \
+ == EFX_MON_STAT_STATE_ ## _field)
+
+static void
+mcdi_mon_decode_stats(
+ __in efx_nic_t *enp,
+ __in_ecount(sensor_mask_size) uint32_t *sensor_mask,
+ __in size_t sensor_mask_size,
+ __in_opt efsys_mem_t *esmp,
+ __out_ecount_opt(sensor_mask_size) uint32_t *stat_maskp,
+ __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *stat)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ uint16_t port_mask;
+ uint16_t sensor;
+ size_t sensor_max;
+ uint32_t stat_mask[(EFX_ARRAY_SIZE(mcdi_sensor_map) + 31) / 32];
+ uint32_t idx = 0;
+ uint32_t page = 0;
+
+ /* Assert the MC_CMD_SENSOR and EFX_MON_STATE namespaces agree */
+ MCDI_STATIC_SENSOR_ASSERT(OK);
+ MCDI_STATIC_SENSOR_ASSERT(WARNING);
+ MCDI_STATIC_SENSOR_ASSERT(FATAL);
+ MCDI_STATIC_SENSOR_ASSERT(BROKEN);
+ MCDI_STATIC_SENSOR_ASSERT(NO_READING);
+
+ EFX_STATIC_ASSERT(sizeof (stat_mask[0]) * 8 ==
+ EFX_MON_MASK_ELEMENT_SIZE);
+ sensor_max =
+ MIN((8 * sensor_mask_size), EFX_ARRAY_SIZE(mcdi_sensor_map));
+
+ port_mask = 1U << emip->emi_port;
+
+ memset(stat_mask, 0, sizeof (stat_mask));
+
+ /*
+ * The MCDI sensor readings in the DMA buffer are a packed array of
+ * MC_CMD_SENSOR_VALUE_ENTRY structures, which only includes entries for
+ * supported sensors (bit set in sensor_mask). The sensor_mask and
+ * sensor readings do not include entries for the per-page NEXT_PAGE
+ * flag.
+ *
+ * sensor_mask may legitimately contain MCDI sensors that the driver
+ * does not understand.
+ */
+ for (sensor = 0; sensor < sensor_max; ++sensor) {
+ efx_mon_stat_t id = mcdi_sensor_map[sensor].msm_stat;
+
+ if ((sensor % MCDI_MON_PAGE_SIZE) == MC_CMD_SENSOR_PAGE0_NEXT) {
+ EFSYS_ASSERT3U(id, ==, MCDI_MON_NEXT_PAGE);
+ page++;
+ continue;
+ }
+ if (~(sensor_mask[page]) & (1U << sensor))
+ continue;
+ idx++;
+
+ if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0)
+ continue;
+ EFSYS_ASSERT(id < EFX_MON_NSTATS);
+
+ /*
+ * stat_mask is a bitmask indexed by EFX_MON_* monitor statistic
+ * identifiers from efx_mon_stat_t (without NEXT_PAGE bits).
+ *
+ * If there is an entry in the MCDI sensor to monitor statistic
+ * map then the sensor reading is used for the value of the
+ * monitor statistic.
+ */
+ stat_mask[id / EFX_MON_MASK_ELEMENT_SIZE] |=
+ (1U << (id % EFX_MON_MASK_ELEMENT_SIZE));
+
+ if (stat != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) {
+ efx_dword_t dword;
+
+ /* Get MCDI sensor reading from DMA buffer */
+ EFSYS_MEM_READD(esmp, 4 * (idx - 1), &dword);
+
+ /* Update EFX monitor stat from MCDI sensor reading */
+ stat[id].emsv_value = (uint16_t)EFX_DWORD_FIELD(dword,
+ MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE);
+
+ stat[id].emsv_state = (uint16_t)EFX_DWORD_FIELD(dword,
+ MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE);
+ }
+ }
+
+ if (stat_maskp != NULL) {
+ memcpy(stat_maskp, stat_mask, sizeof (stat_mask));
+ }
+}
+
+ __checkReturn int
+mcdi_mon_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_mon_stat_t *idp,
+ __out efx_mon_stat_value_t *valuep)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint16_t port_mask;
+ uint16_t sensor;
+ uint16_t state;
+ uint16_t value;
+ efx_mon_stat_t id;
+ int rc;
+
+ port_mask = (emip->emi_port == 1)
+ ? MCDI_MON_PORT_P1
+ : MCDI_MON_PORT_P2;
+
+ sensor = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_MONITOR);
+ state = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_STATE);
+ value = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_VALUE);
+
+ /* Hardware must support this MCDI sensor */
+ EFSYS_ASSERT3U(sensor, <, (8 * encp->enc_mcdi_sensor_mask_size));
+ EFSYS_ASSERT((sensor % MCDI_MON_PAGE_SIZE) != MC_CMD_SENSOR_PAGE0_NEXT);
+ EFSYS_ASSERT(encp->enc_mcdi_sensor_maskp != NULL);
+ EFSYS_ASSERT((encp->enc_mcdi_sensor_maskp[sensor / MCDI_MON_PAGE_SIZE] &
+ (1U << (sensor % MCDI_MON_PAGE_SIZE))) != 0);
+
+ /* But we don't have to understand it */
+ if (sensor >= EFX_ARRAY_SIZE(mcdi_sensor_map)) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ id = mcdi_sensor_map[sensor].msm_stat;
+ if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0)
+ return (ENODEV);
+ EFSYS_ASSERT(id < EFX_MON_NSTATS);
+
+ *idp = id;
+ valuep->emsv_value = value;
+ valuep->emsv_state = state;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_read_sensors(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __in uint32_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_READ_SENSORS_EXT_IN_LEN,
+ MC_CMD_READ_SENSORS_EXT_OUT_LEN)];
+ uint32_t addr_lo, addr_hi;
+
+ req.emr_cmd = MC_CMD_READ_SENSORS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_READ_SENSORS_EXT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_READ_SENSORS_EXT_OUT_LEN;
+
+ addr_lo = (uint32_t)(EFSYS_MEM_ADDR(esmp) & 0xffffffff);
+ addr_hi = (uint32_t)(EFSYS_MEM_ADDR(esmp) >> 32);
+
+ MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_DMA_ADDR_LO, addr_lo);
+ MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_DMA_ADDR_HI, addr_hi);
+ MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_LENGTH, size);
+
+ efx_mcdi_execute(enp, &req);
+
+ return (req.emr_rc);
+}
+
+static __checkReturn int
+efx_mcdi_sensor_info_npages(
+ __in efx_nic_t *enp,
+ __out uint32_t *npagesp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+ MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+ int page;
+ int rc;
+
+ EFSYS_ASSERT(npagesp != NULL);
+
+ page = 0;
+ do {
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SENSOR_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page++);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+ } while (MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK) &
+ (1 << MC_CMD_SENSOR_PAGE0_NEXT));
+
+ *npagesp = page;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_sensor_info(
+ __in efx_nic_t *enp,
+ __out_ecount(npages) uint32_t *sensor_maskp,
+ __in size_t npages)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+ MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+ uint32_t page;
+ int rc;
+
+ EFSYS_ASSERT(sensor_maskp != NULL);
+
+ for (page = 0; page < npages; page++) {
+ uint32_t mask;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SENSOR_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ mask = MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK);
+
+ if ((page != (npages - 1)) &&
+ ((mask & (1U << MC_CMD_SENSOR_PAGE0_NEXT)) == 0)) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ sensor_maskp[page] = mask;
+ }
+
+ if (sensor_maskp[npages - 1] & (1U << MC_CMD_SENSOR_PAGE0_NEXT)) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+mcdi_mon_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t size = encp->enc_mon_stat_dma_buf_size;
+ int rc;
+
+ if ((rc = efx_mcdi_read_sensors(enp, esmp, size)) != 0)
+ goto fail1;
+
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, size);
+
+ mcdi_mon_decode_stats(enp,
+ encp->enc_mcdi_sensor_maskp,
+ encp->enc_mcdi_sensor_mask_size,
+ esmp, NULL, values);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+mcdi_mon_cfg_build(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t npages;
+ int rc;
+
+ switch (enp->en_family) {
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ encp->enc_mon_type = EFX_MON_SFC90X0;
+ break;
+#endif
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ encp->enc_mon_type = EFX_MON_SFC91X0;
+ break;
+#endif
+ default:
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Get mc sensor mask size */
+ npages = 0;
+ if ((rc = efx_mcdi_sensor_info_npages(enp, &npages)) != 0)
+ goto fail2;
+
+ encp->enc_mon_stat_dma_buf_size = npages * EFX_MON_STATS_PAGE_SIZE;
+ encp->enc_mcdi_sensor_mask_size = npages * sizeof (uint32_t);
+
+ /* Allocate mc sensor mask */
+ EFSYS_KMEM_ALLOC(enp->en_esip,
+ encp->enc_mcdi_sensor_mask_size,
+ encp->enc_mcdi_sensor_maskp);
+
+ if (encp->enc_mcdi_sensor_maskp == NULL) {
+ rc = ENOMEM;
+ goto fail3;
+ }
+
+ /* Read mc sensor mask */
+ if ((rc = efx_mcdi_sensor_info(enp,
+ encp->enc_mcdi_sensor_maskp,
+ npages)) != 0)
+ goto fail4;
+
+ /* Build monitor statistics mask */
+ mcdi_mon_decode_stats(enp,
+ encp->enc_mcdi_sensor_maskp,
+ encp->enc_mcdi_sensor_mask_size,
+ NULL, encp->enc_mon_stat_mask, NULL);
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+ EFSYS_KMEM_FREE(enp->en_esip,
+ encp->enc_mcdi_sensor_mask_size,
+ encp->enc_mcdi_sensor_maskp);
+
+fail3:
+ EFSYS_PROBE(fail3);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+mcdi_mon_cfg_free(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+
+ if (encp->enc_mcdi_sensor_maskp != NULL) {
+ EFSYS_KMEM_FREE(enp->en_esip,
+ encp->enc_mcdi_sensor_mask_size,
+ encp->enc_mcdi_sensor_maskp);
+ }
+}
+
+
+#endif /* EFSYS_OPT_MON_STATS */
+
+#endif /* EFSYS_OPT_MON_MCDI */
diff --git a/sys/dev/sfxge/common/mcdi_mon.h b/sys/dev/sfxge/common/mcdi_mon.h
new file mode 100644
index 000000000000..30bb15022581
--- /dev/null
+++ b/sys/dev/sfxge/common/mcdi_mon.h
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_MCDI_MON_H
+#define _SYS_MCDI_MON_H
+
+#include "efx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if EFSYS_OPT_MON_MCDI
+
+#if EFSYS_OPT_MON_STATS
+
+ __checkReturn int
+mcdi_mon_cfg_build(
+ __in efx_nic_t *enp);
+
+ void
+mcdi_mon_cfg_free(
+ __in efx_nic_t *enp);
+
+
+extern __checkReturn int
+mcdi_mon_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_mon_stat_t *idp,
+ __out efx_mon_stat_value_t *valuep);
+
+extern __checkReturn int
+mcdi_mon_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values);
+
+#endif /* EFSYS_OPT_MON_STATS */
+
+#endif /* EFSYS_OPT_MON_MCDI */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MCDI_MON_H */
diff --git a/sys/dev/sfxge/common/siena_flash.h b/sys/dev/sfxge/common/siena_flash.h
index aed688b774e9..c1ee1c5df920 100644
--- a/sys/dev/sfxge/common/siena_flash.h
+++ b/sys/dev/sfxge/common/siena_flash.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -48,6 +53,45 @@
#define SIENA_MC_BOOT_MAGIC (0x51E4A001)
#define SIENA_MC_BOOT_VERSION (1)
+
+/*Structures supporting an arbitrary number of binary blobs in the flash image
+ intended to house code and tables for the satellite cpus*/
+/*thanks to random.org for:*/
+#define BLOBS_HEADER_MAGIC (0xBDA3BBD4)
+#define BLOB_HEADER_MAGIC (0xA1478A91)
+
+typedef struct blobs_hdr_s { /* GENERATED BY scripts/genfwdef */
+ efx_dword_t magic;
+ efx_dword_t no_of_blobs;
+} blobs_hdr_t;
+
+typedef struct blob_hdr_s { /* GENERATED BY scripts/genfwdef */
+ efx_dword_t magic;
+ efx_dword_t cpu_type;
+ efx_dword_t build_variant;
+ efx_dword_t offset;
+ efx_dword_t length;
+ efx_dword_t checksum;
+} blob_hdr_t;
+
+#define BLOB_CPU_TYPE_TXDI_TEXT (0)
+#define BLOB_CPU_TYPE_RXDI_TEXT (1)
+#define BLOB_CPU_TYPE_TXDP_TEXT (2)
+#define BLOB_CPU_TYPE_RXDP_TEXT (3)
+#define BLOB_CPU_TYPE_RXHRSL_HR_LUT (4)
+#define BLOB_CPU_TYPE_RXHRSL_HR_LUT_CFG (5)
+#define BLOB_CPU_TYPE_TXHRSL_HR_LUT (6)
+#define BLOB_CPU_TYPE_TXHRSL_HR_LUT_CFG (7)
+#define BLOB_CPU_TYPE_RXHRSL_HR_PGM (8)
+#define BLOB_CPU_TYPE_RXHRSL_SL_PGM (9)
+#define BLOB_CPU_TYPE_TXHRSL_HR_PGM (10)
+#define BLOB_CPU_TYPE_TXHRSL_SL_PGM (11)
+#define BLOB_CPU_TYPE_RXDI_VTBL0 (12)
+#define BLOB_CPU_TYPE_TXDI_VTBL0 (13)
+#define BLOB_CPU_TYPE_RXDI_VTBL1 (14)
+#define BLOB_CPU_TYPE_TXDI_VTBL1 (15)
+#define BLOB_CPU_TYPE_DUMPSPEC (32)
+
typedef struct siena_mc_boot_hdr_s { /* GENERATED BY scripts/genfwdef */
efx_dword_t magic; /* = SIENA_MC_BOOT_MAGIC */
efx_word_t hdr_version; /* this structure definition is version 1 */
@@ -57,14 +101,21 @@ typedef struct siena_mc_boot_hdr_s { /* GENERATED BY scripts/genfwdef */
efx_byte_t firmware_version_c;
efx_word_t checksum; /* of whole header area + firmware image */
efx_word_t firmware_version_d;
- efx_word_t reserved_a[1]; /* (set to 0) */
+ efx_byte_t mcfw_subtype;
+ efx_byte_t reserved_a[1]; /* (set to 0) */
efx_dword_t firmware_text_offset; /* offset to firmware .text */
efx_dword_t firmware_text_size; /* length of firmware .text, in bytes */
efx_dword_t firmware_data_offset; /* offset to firmware .data */
efx_dword_t firmware_data_size; /* length of firmware .data, in bytes */
- efx_dword_t reserved_b[8]; /* (set to 0) */
+ efx_byte_t spi_rate; /* SPI rate for reading image, 0 is BootROM default */
+ efx_byte_t spi_phase_adj; /* SPI SDO/SCL phase adjustment, 0 is default (no adj) */
+ efx_word_t reserved_b[1]; /* (set to 0) */
+ efx_dword_t reserved_c[7]; /* (set to 0) */
} siena_mc_boot_hdr_t;
+#define SIENA_MC_BOOT_HDR_PADDING \
+ (SIENA_MC_BOOT_HDR_LEN - sizeof(siena_mc_boot_hdr_t))
+
#define SIENA_MC_STATIC_CONFIG_MAGIC (0xBDCF5555)
#define SIENA_MC_STATIC_CONFIG_VERSION (0)
@@ -81,8 +132,8 @@ typedef struct siena_mc_static_config_hdr_s { /* GENERATED BY scripts/genfwdef *
efx_byte_t green_mode_valid; /* Whether cal holds a valid value */
efx_word_t mac_addr_count;
efx_word_t mac_addr_stride;
- efx_word_t calibrated_vref;
- efx_word_t adc_vref;
+ efx_word_t calibrated_vref; /* Vref as measured during production */
+ efx_word_t adc_vref; /* Vref as read by ADC */
efx_dword_t reserved2[1]; /* (write as zero) */
efx_dword_t num_dbi_items;
struct {
@@ -117,17 +168,32 @@ typedef struct siena_mc_dynamic_config_hdr_s { /* GENERATED BY scripts/genfwdef
#define SIENA_MC_EXPROM_SINGLE_MAGIC (0xAA55) /* little-endian uint16_t */
#define SIENA_MC_EXPROM_COMBO_MAGIC (0xB0070102) /* little-endian uint32_t */
+#define SIENA_MC_EXPROM_COMBO_V2_MAGIC (0xB0070103) /* little-endian uint32_t */
typedef struct siena_mc_combo_rom_hdr_s { /* GENERATED BY scripts/genfwdef */
- efx_dword_t magic; /* = SIENA_MC_EXPROM_COMBO_MAGIC */
- efx_dword_t len1; /* length of first image */
- efx_dword_t len2; /* length of second image */
- efx_dword_t off1; /* offset of first byte to edit to combine images */
- efx_dword_t off2; /* offset of second byte to edit to combine images */
- efx_word_t infoblk0_off; /* infoblk offset */
- efx_word_t infoblk1_off; /* infoblk offset */
- efx_byte_t infoblk_len; /* length of space reserved for infoblk structures */
- efx_byte_t reserved[7]; /* (set to 0) */
+ efx_dword_t magic; /* = SIENA_MC_EXPROM_COMBO_MAGIC or SIENA_MC_EXPROM_COMBO_V2_MAGIC */
+ union {
+ struct {
+ efx_dword_t len1; /* length of first image */
+ efx_dword_t len2; /* length of second image */
+ efx_dword_t off1; /* offset of first byte to edit to combine images */
+ efx_dword_t off2; /* offset of second byte to edit to combine images */
+ efx_word_t infoblk0_off;/* infoblk offset */
+ efx_word_t infoblk1_off;/* infoblk offset */
+ efx_byte_t infoblk_len;/* length of space reserved for one infoblk structure */
+ efx_byte_t reserved[7];/* (set to 0) */
+ } v1;
+ struct {
+ efx_dword_t len1; /* length of first image */
+ efx_dword_t len2; /* length of second image */
+ efx_dword_t off1; /* offset of first byte to edit to combine images */
+ efx_dword_t off2; /* offset of second byte to edit to combine images */
+ efx_word_t infoblk_off;/* infoblk start offset */
+ efx_word_t infoblk_count;/* infoblk count */
+ efx_byte_t infoblk_len;/* length of space reserved for one infoblk structure */
+ efx_byte_t reserved[7];/* (set to 0) */
+ } v2;
+ };
} siena_mc_combo_rom_hdr_t;
#pragma pack()
diff --git a/sys/dev/sfxge/common/siena_impl.h b/sys/dev/sfxge/common/siena_impl.h
index 9d0280853b5f..b65e39986ddf 100644
--- a/sys/dev/sfxge/common/siena_impl.h
+++ b/sys/dev/sfxge/common/siena_impl.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -101,6 +106,49 @@ siena_sram_test(
#endif /* EFSYS_OPT_DIAG */
+#if EFSYS_OPT_MCDI
+
+extern __checkReturn int
+siena_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *mtp);
+
+extern void
+siena_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch);
+
+extern __checkReturn boolean_t
+siena_mcdi_request_poll(
+ __in efx_nic_t *enp);
+
+extern void
+siena_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp);
+
+extern int
+siena_mcdi_poll_reboot(
+ __in efx_nic_t *enp);
+
+extern void
+siena_mcdi_fini(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+siena_mcdi_fw_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+extern __checkReturn int
+siena_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+#endif /* EFSYS_OPT_MCDI */
#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
@@ -170,6 +218,12 @@ siena_nvram_size(
__out size_t *sizep);
extern __checkReturn int
+siena_nvram_get_subtype(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __out uint32_t *subtypep);
+
+extern __checkReturn int
siena_nvram_get_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
@@ -212,7 +266,7 @@ extern __checkReturn int
siena_nvram_set_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint16_t version[4]);
+ __in_ecount(4) uint16_t version[4]);
#endif /* EFSYS_OPT_NVRAM */
@@ -341,7 +395,7 @@ siena_phy_stats_update(
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
siena_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id);
@@ -363,18 +417,18 @@ siena_phy_prop_set(
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
extern __checkReturn int
siena_phy_bist_start(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type);
+ __in efx_bist_type_t type);
extern __checkReturn int
siena_phy_bist_poll(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type,
- __out efx_phy_bist_result_t *resultp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
__out_opt __drv_when(count > 0, __notnull)
uint32_t *value_maskp,
__out_ecount_opt(count) __drv_when(count > 0, __notnull)
@@ -384,9 +438,9 @@ siena_phy_bist_poll(
extern void
siena_phy_bist_stop(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type);
+ __in efx_bist_type_t type);
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
extern __checkReturn int
siena_mac_poll(
@@ -415,22 +469,6 @@ siena_mac_loopback_set(
#if EFSYS_OPT_MAC_STATS
extern __checkReturn int
-siena_mac_stats_clear(
- __in efx_nic_t *enp);
-
-extern __checkReturn int
-siena_mac_stats_upload(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp);
-
-extern __checkReturn int
-siena_mac_stats_periodic(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __in uint16_t period_ms,
- __in boolean_t events);
-
-extern __checkReturn int
siena_mac_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
@@ -439,39 +477,6 @@ siena_mac_stats_update(
#endif /* EFSYS_OPT_MAC_STATS */
-extern __checkReturn int
-siena_mon_reset(
- __in efx_nic_t *enp);
-
-extern __checkReturn int
-siena_mon_reconfigure(
- __in efx_nic_t *enp);
-
-#if EFSYS_OPT_MON_STATS
-
-extern void
-siena_mon_decode_stats(
- __in efx_nic_t *enp,
- __in uint32_t dmask,
- __in_opt efsys_mem_t *esmp,
- __out_opt uint32_t *vmaskp,
- __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *value);
-
-extern __checkReturn int
-siena_mon_ev(
- __in efx_nic_t *enp,
- __in efx_qword_t *eqp,
- __out efx_mon_stat_t *idp,
- __out efx_mon_stat_value_t *valuep);
-
-extern __checkReturn int
-siena_mon_stats_update(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values);
-
-#endif /* EFSYS_OPT_MON_STATS */
-
#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/sfxge/common/siena_mac.c b/sys/dev/sfxge/common/siena_mac.c
index 38f5bc5c9353..beeaea1a1c3e 100644
--- a/sys/dev/sfxge/common/siena_mac.c
+++ b/sys/dev/sfxge/common/siena_mac.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -89,26 +94,29 @@ siena_mac_reconfigure(
__in efx_nic_t *enp)
{
efx_port_t *epp = &(enp->en_port);
- uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
- MC_CMD_SET_MCAST_HASH_IN_LEN)];
+ efx_oword_t multicast_hash[2];
efx_mcdi_req_t req;
+ uint8_t payload[MAX(MAX(MC_CMD_SET_MAC_IN_LEN,
+ MC_CMD_SET_MAC_OUT_LEN),
+ MAX(MC_CMD_SET_MCAST_HASH_IN_LEN,
+ MC_CMD_SET_MCAST_HASH_OUT_LEN))];
unsigned int fcntl;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_MAC;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_SET_MAC_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
epp->ep_mac_addr);
MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
- SET_MAC_IN_REJECT_UNCST, !epp->ep_unicst,
- SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);
+ SET_MAC_IN_REJECT_UNCST, !epp->ep_all_unicst,
+ SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);
if (epp->ep_fcntl_autoneg)
/* efx_fcntl_set() has already set the phy capabilities */
@@ -129,19 +137,40 @@ siena_mac_reconfigure(
goto fail1;
}
- /* Push multicast hash. Set the broadcast bit (0xff) appropriately */
+ /* Push multicast hash */
+
+ if (epp->ep_all_mulcst) {
+ /* A hash matching all multicast is all 1s */
+ EFX_SET_OWORD(multicast_hash[0]);
+ EFX_SET_OWORD(multicast_hash[1]);
+ } else if (epp->ep_mulcst) {
+ /* Use the hash set by the multicast list */
+ multicast_hash[0] = epp->ep_multicst_hash[0];
+ multicast_hash[1] = epp->ep_multicst_hash[1];
+ } else {
+ /* A hash matching no traffic is simply 0 */
+ EFX_ZERO_OWORD(multicast_hash[0]);
+ EFX_ZERO_OWORD(multicast_hash[1]);
+ }
+
+ /*
+ * Broadcast packets go through the multicast hash filter.
+ * The IEEE 802.3 CRC32 of the broadcast address is 0xbe2612ff
+ * so we always add bit 0xff to the mask (bit 0x7f in the
+ * second octword).
+ */
+ if (epp->ep_brdcst)
+ EFX_SET_OWORD_BIT(multicast_hash[1], 0x7f);
+
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_MCAST_HASH;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_SET_MCAST_HASH_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_MCAST_HASH_OUT_LEN;
memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0),
- epp->ep_multicst_hash, sizeof (epp->ep_multicst_hash));
- if (epp->ep_brdcst)
- EFX_SET_OWORD_BIT(*MCDI_IN2(req, efx_oword_t,
- SET_MCAST_HASH_IN_HASH1), 0x7f);
+ multicast_hash, sizeof (multicast_hash));
efx_mcdi_execute(enp, &req);
@@ -198,150 +227,6 @@ fail1:
#if EFSYS_OPT_MAC_STATS
- __checkReturn int
-siena_mac_stats_clear(
- __in efx_nic_t *enp)
-{
- uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
- efx_mcdi_req_t req;
- int rc;
-
- req.emr_cmd = MC_CMD_MAC_STATS;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD,
- MAC_STATS_IN_DMA, 0,
- MAC_STATS_IN_CLEAR, 1,
- MAC_STATS_IN_PERIODIC_CHANGE, 0);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
- __checkReturn int
-siena_mac_stats_upload(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp)
-{
- uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
- efx_mcdi_req_t req;
- size_t bytes;
- int rc;
-
- EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <=
- EFX_MAC_STATS_SIZE);
-
- bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
-
- req.emr_cmd = MC_CMD_MAC_STATS;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
- EFSYS_MEM_ADDR(esmp) & 0xffffffff);
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
- EFSYS_MEM_ADDR(esmp) >> 32);
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
-
- /*
- * The MC DMAs aggregate statistics for our convinience, so we can
- * avoid having to pull the statistics buffer into the cache to
- * maintain cumulative statistics.
- */
- MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD,
- MAC_STATS_IN_DMA, 1,
- MAC_STATS_IN_CLEAR, 0,
- MAC_STATS_IN_PERIODIC_CHANGE, 0);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
- __checkReturn int
-siena_mac_stats_periodic(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __in uint16_t period,
- __in boolean_t events)
-{
- uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
- efx_mcdi_req_t req;
- size_t bytes;
- int rc;
-
- bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
-
- req.emr_cmd = MC_CMD_MAC_STATS;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
- EFSYS_MEM_ADDR(esmp) & 0xffffffff);
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
- EFSYS_MEM_ADDR(esmp) >> 32);
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
-
- /*
- * The MC DMAs aggregate statistics for our convinience, so we can
- * avoid having to pull the statistics buffer into the cache to
- * maintain cumulative statistics.
- */
- MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD,
- MAC_STATS_IN_DMA, 0,
- MAC_STATS_IN_CLEAR, 0,
- MAC_STATS_IN_PERIODIC_CHANGE, 1,
- MAC_STATS_IN_PERIODIC_ENABLE, period ? 1 : 0,
- MAC_STATS_IN_PERIODIC_NOEVENT, events ? 0 : 1,
- MAC_STATS_IN_PERIOD_MS, period);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-
#define SIENA_MAC_STAT_READ(_esmp, _field, _eqp) \
EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
@@ -352,7 +237,6 @@ siena_mac_stats_update(
__out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
__out_opt uint32_t *generationp)
{
- efx_qword_t rx_pkts;
efx_qword_t value;
efx_qword_t generation_start;
efx_qword_t generation_end;
@@ -360,6 +244,7 @@ siena_mac_stats_update(
_NOTE(ARGUNUSED(enp))
/* Read END first so we don't race with the MC */
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
&generation_end);
EFSYS_MEM_READ_BARRIER();
@@ -388,7 +273,7 @@ siena_mac_stats_update(
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
- EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
@@ -435,8 +320,8 @@ siena_mac_stats_update(
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
/* RX */
- SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &rx_pkts);
- EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &rx_pkts);
+ SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value);
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
@@ -529,6 +414,7 @@ siena_mac_stats_update(
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
EFSYS_MEM_READ_BARRIER();
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
&generation_start);
diff --git a/sys/dev/sfxge/common/siena_mcdi.c b/sys/dev/sfxge/common/siena_mcdi.c
new file mode 100644
index 000000000000..b2224acdef70
--- /dev/null
+++ b/sys/dev/sfxge/common/siena_mcdi.c
@@ -0,0 +1,354 @@
+/*-
+ * Copyright (c) 2012-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_SIENA && EFSYS_OPT_MCDI
+
+#define SIENA_MCDI_PDU(_emip) \
+ (((emip)->emi_port == 1) \
+ ? MC_SMEM_P0_PDU_OFST >> 2 \
+ : MC_SMEM_P1_PDU_OFST >> 2)
+
+#define SIENA_MCDI_DOORBELL(_emip) \
+ (((emip)->emi_port == 1) \
+ ? MC_SMEM_P0_DOORBELL_OFST >> 2 \
+ : MC_SMEM_P1_DOORBELL_OFST >> 2)
+
+#define SIENA_MCDI_STATUS(_emip) \
+ (((emip)->emi_port == 1) \
+ ? MC_SMEM_P0_STATUS_OFST >> 2 \
+ : MC_SMEM_P1_STATUS_OFST >> 2)
+
+
+ void
+siena_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_dword_t dword;
+ unsigned int xflags;
+ unsigned int pdur;
+ unsigned int dbr;
+ unsigned int pos;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+ _NOTE(ARGUNUSED(new_epoch))
+
+ EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
+ pdur = SIENA_MCDI_PDU(emip);
+ dbr = SIENA_MCDI_DOORBELL(emip);
+
+ xflags = 0;
+ if (ev_cpl)
+ xflags |= MCDI_HEADER_XFLAGS_EVREQ;
+
+ /* Construct the header in shared memory */
+ EFX_POPULATE_DWORD_6(dword,
+ MCDI_HEADER_CODE, emrp->emr_cmd,
+ MCDI_HEADER_RESYNC, 1,
+ MCDI_HEADER_DATALEN, emrp->emr_in_length,
+ MCDI_HEADER_SEQ, seq,
+ MCDI_HEADER_RESPONSE, 0,
+ MCDI_HEADER_XFLAGS, xflags);
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE);
+
+ for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
+ memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
+ MIN(sizeof (dword), emrp->emr_in_length - pos));
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,
+ pdur + 1 + (pos >> 2), &dword, B_FALSE);
+ }
+
+ /* Ring the doorbell */
+ EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
+}
+
+ void
+siena_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ unsigned int pos;
+ unsigned int pdur;
+ efx_dword_t data;
+
+ pdur = SIENA_MCDI_PDU(emip);
+
+ /* Copy payload out if caller supplied buffer */
+ if (emrp->emr_out_buf != NULL) {
+ size_t bytes = MIN(emrp->emr_out_length_used,
+ emrp->emr_out_length);
+ for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) {
+ EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
+ pdur + 1 + (pos >> 2), &data, B_FALSE);
+ memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
+ MIN(sizeof (data), bytes - pos));
+ }
+ }
+}
+
+ int
+siena_mcdi_poll_reboot(
+ __in efx_nic_t *enp)
+{
+#ifndef EFX_GRACEFUL_MC_REBOOT
+ /*
+ * This function is not being used properly.
+ * Until its callers are fixed, it should always return 0.
+ */
+ _NOTE(ARGUNUSED(enp))
+ return (0);
+#else
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ unsigned int rebootr;
+ efx_dword_t dword;
+ uint32_t value;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+ EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
+ rebootr = SIENA_MCDI_STATUS(emip);
+
+ EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);
+ value = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
+
+ if (value == 0)
+ return (0);
+
+ EFX_ZERO_DWORD(dword);
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);
+
+ if (value == MC_STATUS_DWORD_ASSERT)
+ return (EINTR);
+ else
+ return (EIO);
+#endif
+}
+
+ __checkReturn boolean_t
+siena_mcdi_request_poll(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_req_t *emrp;
+ efx_dword_t dword;
+ unsigned int pdur;
+ unsigned int seq;
+ unsigned int length;
+ int state;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
+
+ /* Serialise against post-watchdog efx_mcdi_ev* */
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ EFSYS_ASSERT(emip->emi_pending_req != NULL);
+ EFSYS_ASSERT(!emip->emi_ev_cpl);
+ emrp = emip->emi_pending_req;
+
+ /* Check for reboot atomically w.r.t efx_mcdi_request_start */
+ if (emip->emi_poll_cnt++ == 0) {
+ if ((rc = siena_mcdi_poll_reboot(enp)) != 0) {
+ emip->emi_pending_req = NULL;
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ goto fail1;
+ }
+ }
+
+ EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
+ pdur = SIENA_MCDI_PDU(emip);
+
+ /* Read the command header */
+ EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_FALSE);
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (B_FALSE);
+ }
+
+ /* Request complete */
+ emip->emi_pending_req = NULL;
+ seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
+
+ /* Check for synchronous reboot */
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 &&
+ EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN) == 0) {
+ /* Consume status word */
+ EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
+ siena_mcdi_poll_reboot(enp);
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ rc = EIO;
+ goto fail2;
+ }
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ /* Check that the returned data is consistent */
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) != emrp->emr_cmd ||
+ EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
+ /* Response is for a different request */
+ rc = EIO;
+ goto fail3;
+ }
+
+ length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
+ efx_dword_t errdword;
+ int errcode;
+
+ EFSYS_ASSERT3U(length, ==, 4);
+ EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
+ pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2),
+ &errdword, B_FALSE);
+ errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
+ rc = efx_mcdi_request_errcode(errcode);
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
+ int, errcode);
+ }
+ goto fail4;
+
+ } else {
+ emrp->emr_out_length_used = length;
+ emrp->emr_rc = 0;
+ siena_mcdi_request_copyout(enp, emrp);
+ }
+
+ goto out;
+
+fail4:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail4);
+fail3:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail3);
+fail2:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail2);
+fail1:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE1(fail1, int, rc);
+
+ /* Fill out error state */
+ emrp->emr_rc = rc;
+ emrp->emr_out_length_used = 0;
+
+ /* Reboot/Assertion */
+ if (rc == EIO || rc == EINTR)
+ efx_mcdi_raise_exception(enp, emrp, rc);
+
+out:
+ return (B_TRUE);
+}
+
+ __checkReturn int
+siena_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *mtp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_oword_t oword;
+ unsigned int portnum;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+
+ /* Determine the port number to use for MCDI */
+ EFX_BAR_READO(enp, FR_AZ_CS_DEBUG_REG, &oword);
+ portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);
+
+ if (portnum == 0) {
+ /* Presumably booted from ROM; only MCDI port 1 will work */
+ emip->emi_port = 1;
+ } else if (portnum <= 2) {
+ emip->emi_port = portnum;
+ } else {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /*
+ * Wipe the atomic reboot status so subsequent MCDI requests succeed.
+ * BOOT_STATUS is preserved so eno_nic_probe() can boot out of the
+ * assertion handler.
+ */
+ (void) siena_mcdi_poll_reboot(enp);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+siena_mcdi_fini(
+ __in efx_nic_t *enp)
+{
+}
+
+ __checkReturn int
+siena_mcdi_fw_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
+
+ *supportedp = B_TRUE;
+
+ return (0);
+}
+
+ __checkReturn int
+siena_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
+
+ *supportedp = B_TRUE;
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_SIENA && EFSYS_OPT_MCDI */
diff --git a/sys/dev/sfxge/common/siena_mon.c b/sys/dev/sfxge/common/siena_mon.c
deleted file mode 100644
index 227ff155e8cc..000000000000
--- a/sys/dev/sfxge/common/siena_mon.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*-
- * Copyright 2009 Solarflare Communications Inc. 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "efsys.h"
-#include "efx.h"
-#include "efx_impl.h"
-
-#if EFSYS_OPT_MON_SIENA
-
- __checkReturn int
-siena_mon_reset(
- __in efx_nic_t *enp)
-{
- _NOTE(ARGUNUSED(enp))
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
-
- return (0);
-}
-
- __checkReturn int
-siena_mon_reconfigure(
- __in efx_nic_t *enp)
-{
- _NOTE(ARGUNUSED(enp))
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
-
- return (0);
-}
-
-#if EFSYS_OPT_MON_STATS
-
-#define SIENA_MON_WRONG_PORT (uint16_t)0xffff
-
-static __cs uint16_t __siena_mon_port0_map[] = {
- EFX_MON_STAT_INT_TEMP, /* MC_CMD_SENSOR_CONTROLLER_TEMP */
- EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY_COMMON_TEMP */
- EFX_MON_STAT_INT_COOLING, /* MC_CMD_SENSOR_CONTROLLER_COOLING */
- EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY0_TEMP */
- EFX_MON_STAT_EXT_COOLING, /* MC_CMD_SENSOR_PHY0_COOLING */
- SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY1_TEMP */
- SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY1_COOLING */
- EFX_MON_STAT_1V, /* MC_CMD_SENSOR_IN_1V0 */
- EFX_MON_STAT_1_2V, /* MC_CMD_SENSOR_IN_1V2 */
- EFX_MON_STAT_1_8V, /* MC_CMD_SENSOR_IN_1V8 */
- EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */
- EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */
- EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */
- EFX_MON_STAT_1_2VA, /* MC_CMD_SENSOR_IN_1V2A */
- EFX_MON_STAT_VREF, /* MC_CMD_SENSOR_IN_VREF */
- EFX_MON_STAT_VAOE, /* MC_CMD_SENSOR_OUT_VAOE */
- EFX_MON_STAT_AOE_TEMP, /* MC_CMD_SENSOR_AOE_TEMP */
- EFX_MON_STAT_PSU_AOE_TEMP, /* MC_CMD_SENSOR_PSU_AOE_TEMP */
- EFX_MON_STAT_PSU_TEMP, /* MC_CMD_SENSOR_PSE_TEMP */
- EFX_MON_STAT_FAN0, /* MC_CMD_SENSOR_FAN_0 */
- EFX_MON_STAT_FAN1, /* MC_CMD_SENSOR_FAN_1 */
- EFX_MON_STAT_FAN2, /* MC_CMD_SENSOR_FAN_2 */
- EFX_MON_STAT_FAN3, /* MC_CMD_SENSOR_FAN_3 */
- EFX_MON_STAT_FAN4, /* MC_CMD_SENSOR_FAN_4 */
- EFX_MON_STAT_VAOE_IN, /* MC_CMD_SENSOR_IN_VAOE */
- EFX_MON_STAT_IAOE, /* MC_CMD_SENSOR_OUT_IAOE */
- EFX_MON_STAT_IAOE_IN, /* MC_CMD_SENSOR_IN_IAOE */
-
-};
-
-static __cs uint16_t __siena_mon_port1_map[] = {
- EFX_MON_STAT_INT_TEMP, /* MC_CMD_SENSOR_CONTROLLER_TEMP */
- EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY_COMMON_TEMP */
- EFX_MON_STAT_INT_COOLING, /* MC_CMD_SENSOR_CONTROLLER_COOLING */
- SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY0_TEMP */
- SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY0_COOLING */
- EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY1_TEMP */
- EFX_MON_STAT_EXT_COOLING, /* MC_CMD_SENSOR_PHY1_COOLING */
- EFX_MON_STAT_1V, /* MC_CMD_SENSOR_IN_1V0 */
- EFX_MON_STAT_1_2V, /* MC_CMD_SENSOR_IN_1V2 */
- EFX_MON_STAT_1_8V, /* MC_CMD_SENSOR_IN_1V8 */
- EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */
- EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */
- EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */
- EFX_MON_STAT_1_2VA, /* MC_CMD_SENSOR_IN_1V2A */
- EFX_MON_STAT_VREF, /* MC_CMD_SENSOR_IN_VREF */
- EFX_MON_STAT_VAOE, /* MC_CMD_SENSOR_OUT_VAOE */
- EFX_MON_STAT_AOE_TEMP, /* MC_CMD_SENSOR_AOE_TEMP */
- EFX_MON_STAT_PSU_AOE_TEMP, /* MC_CMD_SENSOR_PSU_AOE_TEMP */
- EFX_MON_STAT_PSU_TEMP, /* MC_CMD_SENSOR_PSE_TEMP */
- EFX_MON_STAT_FAN0, /* MC_CMD_SENSOR_FAN_0 */
- EFX_MON_STAT_FAN1, /* MC_CMD_SENSOR_FAN_1 */
- EFX_MON_STAT_FAN2, /* MC_CMD_SENSOR_FAN_2 */
- EFX_MON_STAT_FAN3, /* MC_CMD_SENSOR_FAN_3 */
- EFX_MON_STAT_FAN4, /* MC_CMD_SENSOR_FAN_4 */
- EFX_MON_STAT_VAOE_IN, /* MC_CMD_SENSOR_IN_VAOE */
- EFX_MON_STAT_IAOE, /* MC_CMD_SENSOR_OUT_IAOE */
- EFX_MON_STAT_IAOE_IN, /* MC_CMD_SENSOR_IN_IAOE */
-
-};
-
-#define SIENA_STATIC_SENSOR_ASSERT(_field) \
- EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \
- == EFX_MON_STAT_STATE_ ## _field)
-
- void
-siena_mon_decode_stats(
- __in efx_nic_t *enp,
- __in uint32_t dmask,
- __in_opt efsys_mem_t *esmp,
- __out_opt uint32_t *vmaskp,
- __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *value)
-{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- uint16_t *sensor_map;
- uint16_t mc_sensor;
- size_t mc_sensor_max;
- uint32_t vmask = 0;
- uint32_t idx = 0;
-
- /* Assert the MC_CMD_SENSOR and EFX_MON_STATE namespaces agree */
- SIENA_STATIC_SENSOR_ASSERT(OK);
- SIENA_STATIC_SENSOR_ASSERT(WARNING);
- SIENA_STATIC_SENSOR_ASSERT(FATAL);
- SIENA_STATIC_SENSOR_ASSERT(BROKEN);
-
- EFX_STATIC_ASSERT(sizeof (__siena_mon_port1_map)
- == sizeof (__siena_mon_port0_map));
- mc_sensor_max = EFX_ARRAY_SIZE(__siena_mon_port0_map);
- sensor_map = (emip->emi_port == 1)
- ? __siena_mon_port0_map
- : __siena_mon_port1_map;
-
- /*
- * dmask may legitimately contain sensors not understood by the driver
- */
- for (mc_sensor = 0; mc_sensor < mc_sensor_max; ++mc_sensor) {
- uint16_t efx_sensor = sensor_map[mc_sensor];
-
- if (~dmask & (1 << mc_sensor))
- continue;
- idx++;
-
- if (efx_sensor == SIENA_MON_WRONG_PORT)
- continue;
- EFSYS_ASSERT(efx_sensor < EFX_MON_NSTATS);
-
- vmask |= (1 << efx_sensor);
- if (value != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) {
- efx_mon_stat_value_t *emsvp = value + efx_sensor;
- efx_dword_t dword;
- EFSYS_MEM_READD(esmp, 4 * (idx - 1), &dword);
- emsvp->emsv_value =
- (uint16_t)EFX_DWORD_FIELD(
- dword,
- MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE);
- emsvp->emsv_state =
- (uint16_t)EFX_DWORD_FIELD(
- dword,
- MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE);
- }
- }
-
- if (vmaskp != NULL)
- *vmaskp = vmask;
-}
-
- __checkReturn int
-siena_mon_ev(
- __in efx_nic_t *enp,
- __in efx_qword_t *eqp,
- __out efx_mon_stat_t *idp,
- __out efx_mon_stat_value_t *valuep)
-{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint16_t ev_monitor;
- uint16_t ev_state;
- uint16_t ev_value;
- uint16_t *sensor_map;
- efx_mon_stat_t id;
- int rc;
-
- sensor_map = (emip->emi_port == 1)
- ? __siena_mon_port0_map
- : __siena_mon_port1_map;
-
- ev_monitor = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_MONITOR);
- ev_state = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_STATE);
- ev_value = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_VALUE);
-
- /* Hardware must support this statistic */
- EFSYS_ASSERT((1 << ev_monitor) & encp->enc_siena_mon_stat_mask);
-
- /* But we don't have to understand it */
- if (ev_monitor >= EFX_ARRAY_SIZE(__siena_mon_port0_map)) {
- rc = ENOTSUP;
- goto fail1;
- }
-
- id = sensor_map[ev_monitor];
- if (id == SIENA_MON_WRONG_PORT)
- return (ENODEV);
- EFSYS_ASSERT(id < EFX_MON_NSTATS);
-
- *idp = id;
- valuep->emsv_value = ev_value;
- valuep->emsv_state = ev_state;
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
- __checkReturn int
-siena_mon_stats_update(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t dmask = encp->enc_siena_mon_stat_mask;
- uint32_t vmask;
- uint8_t payload[MC_CMD_READ_SENSORS_IN_LEN];
- efx_mcdi_req_t req;
- int rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
-
- req.emr_cmd = MC_CMD_READ_SENSORS;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_READ_SENSORS_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, READ_SENSORS_IN_DMA_ADDR_LO,
- EFSYS_MEM_ADDR(esmp) & 0xffffffff);
- MCDI_IN_SET_DWORD(req, READ_SENSORS_IN_DMA_ADDR_HI,
- EFSYS_MEM_ADDR(esmp) >> 32);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- siena_mon_decode_stats(enp, dmask, esmp, &vmask, values);
- EFSYS_ASSERT(vmask == encp->enc_mon_stat_mask);
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-#endif /* EFSYS_OPT_MON_STATS */
-
-#endif /* EFSYS_OPT_MON_SIENA */
diff --git a/sys/dev/sfxge/common/siena_nic.c b/sys/dev/sfxge/common/siena_nic.c
index 1276c9374582..3dcf48ec6cdb 100644
--- a/sys/dev/sfxge/common/siena_nic.c
+++ b/sys/dev/sfxge/common/siena_nic.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -29,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include "efsys.h"
#include "efx.h"
#include "efx_impl.h"
+#include "mcdi_mon.h"
#if EFSYS_OPT_SIENA
@@ -38,15 +44,16 @@ siena_nic_get_partn_mask(
__out unsigned int *maskp)
{
efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_NVRAM_TYPES_OUT_LEN];
+ uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
+ MC_CMD_NVRAM_TYPES_OUT_LEN)];
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_TYPES;
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_TYPES_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
efx_mcdi_execute(enp, &req);
@@ -72,193 +79,17 @@ fail1:
return (rc);
}
-static __checkReturn int
-siena_nic_exit_assertion_handler(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_REBOOT_IN_LEN];
- int rc;
-
- req.emr_cmd = MC_CMD_REBOOT;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_REBOOT_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS,
- MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0 && req.emr_rc != EIO) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-static __checkReturn int
-siena_nic_read_assertion(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_ASSERTS_IN_LEN,
- MC_CMD_GET_ASSERTS_OUT_LEN)];
- const char *reason;
- unsigned int flags;
- unsigned int index;
- unsigned int ofst;
- int retry;
- int rc;
-
- /*
- * Before we attempt to chat to the MC, we should verify that the MC
- * isn't in it's assertion handler, either due to a previous reboot,
- * or because we're reinitializing due to an eec_exception().
- *
- * Use GET_ASSERTS to read any assertion state that may be present.
- * Retry this command twice. Once because a boot-time assertion failure
- * might cause the 1st MCDI request to fail. And once again because
- * we might race with siena_nic_exit_assertion_handler() running on the
- * other port.
- */
- retry = 2;
- do {
- req.emr_cmd = MC_CMD_GET_ASSERTS;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_ASSERTS_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_ASSERTS_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, GET_ASSERTS_IN_CLEAR, 1);
- efx_mcdi_execute(enp, &req);
-
- } while ((req.emr_rc == EINTR || req.emr_rc == EIO) && retry-- > 0);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_ASSERTS_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- /* Print out any assertion state recorded */
- flags = MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_GLOBAL_FLAGS);
- if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
- return (0);
-
- reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
- ? "system-level assertion"
- : (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
- ? "thread-level assertion"
- : (flags == MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED)
- ? "watchdog reset"
- : "unknown assertion";
- EFSYS_PROBE3(mcpu_assertion,
- const char *, reason, unsigned int,
- MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_SAVED_PC_OFFS),
- unsigned int,
- MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_THREAD_OFFS));
-
- /* Print out the registers */
- ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
- for (index = 1; index < 32; index++) {
- EFSYS_PROBE2(mcpu_register, unsigned int, index, unsigned int,
- EFX_DWORD_FIELD(*MCDI_OUT(req, efx_dword_t, ofst),
- EFX_DWORD_0));
- ofst += sizeof (efx_dword_t);
- }
- EFSYS_ASSERT(ofst <= MC_CMD_GET_ASSERTS_OUT_LEN);
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-static __checkReturn int
-siena_nic_attach(
- __in efx_nic_t *enp,
- __in boolean_t attach)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_DRV_ATTACH_IN_LEN];
- int rc;
-
- req.emr_cmd = MC_CMD_DRV_ATTACH;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_NEW_STATE, attach ? 1 : 0);
- MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_UPDATE, 1);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
#if EFSYS_OPT_PCIE_TUNE
__checkReturn int
siena_nic_pcie_extended_sync(
__in efx_nic_t *enp)
{
- uint8_t inbuf[MC_CMD_WORKAROUND_IN_LEN];
- efx_mcdi_req_t req;
int rc;
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
-
- req.emr_cmd = MC_CMD_WORKAROUND;
- req.emr_in_buf = inbuf;
- req.emr_in_length = sizeof (inbuf);
- EFX_STATIC_ASSERT(MC_CMD_WORKAROUND_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, WORKAROUND_IN_TYPE, MC_CMD_WORKAROUND_BUG17230);
- MCDI_IN_SET_DWORD(req, WORKAROUND_IN_ENABLED, 1);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG17230,
+ B_TRUE, NULL) != 0))
goto fail1;
- }
return (0);
@@ -275,58 +106,33 @@ siena_board_cfg(
__in efx_nic_t *enp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- uint8_t outbuf[MAX(MC_CMD_GET_BOARD_CFG_OUT_LENMIN,
- MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
- efx_mcdi_req_t req;
- uint8_t *mac_addr;
- efx_dword_t *capabilities;
+ uint8_t mac_addr[6];
+ efx_dword_t capabilities;
+ uint32_t board_type;
+ uint32_t nevq, nrxq, ntxq;
int rc;
- /* Board configuration */
- req.emr_cmd = MC_CMD_GET_BOARD_CFG;
- EFX_STATIC_ASSERT(MC_CMD_GET_BOARD_CFG_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LENMIN;
-
- efx_mcdi_execute(enp, &req);
+ /* External port identifier using one-based port numbering */
+ encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ /* Board configuration */
+ if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
+ &capabilities, mac_addr)) != 0)
goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_BOARD_CFG_OUT_LENMIN) {
- rc = EMSGSIZE;
- goto fail2;
- }
- if (emip->emi_port == 1) {
- mac_addr = MCDI_OUT2(req, uint8_t,
- GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0);
- capabilities = MCDI_OUT2(req, efx_dword_t,
- GET_BOARD_CFG_OUT_CAPABILITIES_PORT0);
- } else {
- mac_addr = MCDI_OUT2(req, uint8_t,
- GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1);
- capabilities = MCDI_OUT2(req, efx_dword_t,
- GET_BOARD_CFG_OUT_CAPABILITIES_PORT1);
- }
EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
- encp->enc_board_type = MCDI_OUT_DWORD(req,
- GET_BOARD_CFG_OUT_BOARD_TYPE);
+ encp->enc_board_type = board_type;
/* Additional capabilities */
encp->enc_clk_mult = 1;
- if (MCDI_CMD_DWORD_FIELD(capabilities, CAPABILITIES_TURBO)) {
+ if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
enp->en_features |= EFX_FEATURE_TURBO;
- if (MCDI_CMD_DWORD_FIELD(capabilities,
- CAPABILITIES_TURBO_ACTIVE))
+ if (EFX_DWORD_FIELD(capabilities,
+ MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
encp->enc_clk_mult = 2;
+ }
}
encp->enc_evq_timer_quantum_ns =
@@ -334,48 +140,39 @@ siena_board_cfg(
encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
- /* Resource limits */
- req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
- EFX_STATIC_ASSERT(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN;
+ /* When hash header insertion is enabled, Siena inserts 16 bytes */
+ encp->enc_rx_prefix_size = 16;
- efx_mcdi_execute(enp, &req);
+ /* Alignment for receive packet DMA buffers */
+ encp->enc_rx_buf_align_start = 1;
+ encp->enc_rx_buf_align_end = 1;
- if (req.emr_rc == 0) {
- if (req.emr_out_length_used <
- MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail3;
- }
+ /* Alignment for WPTR updates */
+ encp->enc_rx_push_align = 1;
- encp->enc_evq_limit = MCDI_OUT_DWORD(req,
- GET_RESOURCE_LIMITS_OUT_EVQ);
- encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET,
- MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_TXQ));
- encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET,
- MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_RXQ));
- } else if (req.emr_rc == ENOTSUP) {
- encp->enc_evq_limit = 1024;
- encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
- encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
- } else {
- rc = req.emr_rc;
- goto fail4;
+ /* Resource limits */
+ rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
+ if (rc != 0) {
+ if (rc != ENOTSUP)
+ goto fail2;
+
+ nevq = 1024;
+ nrxq = EFX_RXQ_LIMIT_TARGET;
+ ntxq = EFX_TXQ_LIMIT_TARGET;
}
+ encp->enc_evq_limit = nevq;
+ encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
+ encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
(encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
(encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
+ encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
+ encp->enc_fw_assisted_tso_enabled = B_FALSE;
+
return (0);
-fail4:
- EFSYS_PROBE(fail4);
-fail3:
- EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
@@ -388,220 +185,27 @@ static __checkReturn int
siena_phy_cfg(
__in efx_nic_t *enp)
{
- efx_port_t *epp = &(enp->en_port);
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_PHY_CFG_OUT_LEN];
int rc;
- req.emr_cmd = MC_CMD_GET_PHY_CFG;
- EFX_STATIC_ASSERT(MC_CMD_GET_PHY_CFG_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
+ if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- encp->enc_phy_type = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_TYPE);
-#if EFSYS_OPT_NAMES
- (void) strncpy(encp->enc_phy_name,
- MCDI_OUT2(req, char, GET_PHY_CFG_OUT_NAME),
- MIN(sizeof (encp->enc_phy_name) - 1,
- MC_CMD_GET_PHY_CFG_OUT_NAME_LEN));
-#endif /* EFSYS_OPT_NAMES */
- (void) memset(encp->enc_phy_revision, 0,
- sizeof (encp->enc_phy_revision));
- memcpy(encp->enc_phy_revision,
- MCDI_OUT2(req, char, GET_PHY_CFG_OUT_REVISION),
- MIN(sizeof (encp->enc_phy_revision) - 1,
- MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN));
-#if EFSYS_OPT_PHY_LED_CONTROL
- encp->enc_led_mask = ((1 << EFX_PHY_LED_DEFAULT) |
- (1 << EFX_PHY_LED_OFF) |
- (1 << EFX_PHY_LED_ON));
-#endif /* EFSYS_OPT_PHY_LED_CONTROL */
-
-#if EFSYS_OPT_PHY_PROPS
- encp->enc_phy_nprops = 0;
-#endif /* EFSYS_OPT_PHY_PROPS */
-
- /* Get the media type of the fixed port, if recognised. */
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_XAUI == EFX_PHY_MEDIA_XAUI);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_CX4 == EFX_PHY_MEDIA_CX4);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_KX4 == EFX_PHY_MEDIA_KX4);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_XFP == EFX_PHY_MEDIA_XFP);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_SFP_PLUS == EFX_PHY_MEDIA_SFP_PLUS);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_BASE_T == EFX_PHY_MEDIA_BASE_T);
- epp->ep_fixed_port_type =
- MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_MEDIA_TYPE);
- if (epp->ep_fixed_port_type >= EFX_PHY_MEDIA_NTYPES)
- epp->ep_fixed_port_type = EFX_PHY_MEDIA_INVALID;
-
- epp->ep_phy_cap_mask =
- MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_SUPPORTED_CAP);
-#if EFSYS_OPT_PHY_FLAGS
- encp->enc_phy_flags_mask = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_FLAGS);
-#endif /* EFSYS_OPT_PHY_FLAGS */
-
- encp->enc_port = (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_PRT);
-
- /* Populate internal state */
- encp->enc_siena_channel =
- (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_CHANNEL);
#if EFSYS_OPT_PHY_STATS
- encp->enc_siena_phy_stat_mask =
- MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_STATS_MASK);
-
/* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
- siena_phy_decode_stats(enp, encp->enc_siena_phy_stat_mask,
+ siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
NULL, &encp->enc_phy_stat_mask, NULL);
#endif /* EFSYS_OPT_PHY_STATS */
-#if EFSYS_OPT_PHY_BIST
- encp->enc_bist_mask = 0;
- if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
- GET_PHY_CFG_OUT_BIST_CABLE_SHORT))
- encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_SHORT);
- if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
- GET_PHY_CFG_OUT_BIST_CABLE_LONG))
- encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_LONG);
- if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
- GET_PHY_CFG_OUT_BIST))
- encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_NORMAL);
-#endif /* EFSYS_OPT_PHY_BIST */
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-#if EFSYS_OPT_LOOPBACK
-
-static __checkReturn int
-siena_loopback_cfg(
- __in efx_nic_t *enp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_LOOPBACK_MODES_OUT_LEN];
- int rc;
-
- req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
- EFX_STATIC_ASSERT(MC_CMD_GET_LOOPBACK_MODES_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_LOOPBACK_MODES_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- /*
- * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
- * in siena_phy.c:siena_phy_get_link()
- */
- encp->enc_loopback_types[EFX_LINK_100FDX] = EFX_LOOPBACK_MASK &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_100M) &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
- encp->enc_loopback_types[EFX_LINK_1000FDX] = EFX_LOOPBACK_MASK &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_1G) &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
- encp->enc_loopback_types[EFX_LINK_10000FDX] = EFX_LOOPBACK_MASK &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_10G) &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
- encp->enc_loopback_types[EFX_LINK_UNKNOWN] =
- (1 << EFX_LOOPBACK_OFF) |
- encp->enc_loopback_types[EFX_LINK_100FDX] |
- encp->enc_loopback_types[EFX_LINK_1000FDX] |
- encp->enc_loopback_types[EFX_LINK_10000FDX];
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-#endif /* EFSYS_OPT_LOOPBACK */
-
-#if EFSYS_OPT_MON_STATS
-
-static __checkReturn int
-siena_monitor_cfg(
- __in efx_nic_t *enp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_mcdi_req_t req;
- uint8_t outbuf[MCDI_CTL_SDU_LEN_MAX];
- int rc;
-
- req.emr_cmd = MC_CMD_SENSOR_INFO;
- EFX_STATIC_ASSERT(MC_CMD_SENSOR_INFO_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_SENSOR_INFO_OUT_MASK_OFST + 4) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- encp->enc_siena_mon_stat_mask =
- MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK);
- encp->enc_mon_type = EFX_MON_SFC90X0;
-
- siena_mon_decode_stats(enp, encp->enc_siena_mon_stat_mask,
- NULL, &(encp->enc_mon_stat_mask), NULL);
-
return (0);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
return (rc);
}
-#endif /* EFSYS_OPT_MON_STATS */
-
__checkReturn int
siena_nic_probe(
__in efx_nic_t *enp)
@@ -610,56 +214,69 @@ siena_nic_probe(
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
siena_link_state_t sls;
unsigned int mask;
+ efx_oword_t oword;
int rc;
EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
- /* Read clear any assertion state */
- if ((rc = siena_nic_read_assertion(enp)) != 0)
+ /* Test BIU */
+ if ((rc = efx_nic_biu_test(enp)) != 0)
goto fail1;
- /* Exit the assertion handler */
- if ((rc = siena_nic_exit_assertion_handler(enp)) != 0)
+ /* Clear the region register */
+ EFX_POPULATE_OWORD_4(oword,
+ FRF_AZ_ADR_REGION0, 0,
+ FRF_AZ_ADR_REGION1, (1 << 16),
+ FRF_AZ_ADR_REGION2, (2 << 16),
+ FRF_AZ_ADR_REGION3, (3 << 16));
+ EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
+
+ /* Read clear any assertion state */
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
goto fail2;
- /* Wrestle control from the BMC */
- if ((rc = siena_nic_attach(enp, B_TRUE)) != 0)
+ /* Exit the assertion handler */
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
goto fail3;
- if ((rc = siena_board_cfg(enp)) != 0)
+ /* Wrestle control from the BMC */
+ if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
goto fail4;
- if ((rc = siena_phy_cfg(enp)) != 0)
+ if ((rc = siena_board_cfg(enp)) != 0)
goto fail5;
+ if ((rc = siena_phy_cfg(enp)) != 0)
+ goto fail6;
+
/* Obtain the default PHY advertised capabilities */
if ((rc = siena_nic_reset(enp)) != 0)
- goto fail6;
- if ((rc = siena_phy_get_link(enp, &sls)) != 0)
goto fail7;
+ if ((rc = siena_phy_get_link(enp, &sls)) != 0)
+ goto fail8;
epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
- goto fail8;
+ goto fail9;
enp->en_u.siena.enu_partn_mask = mask;
#endif
#if EFSYS_OPT_MAC_STATS
/* Wipe the MAC statistics */
- if ((rc = siena_mac_stats_clear(enp)) != 0)
- goto fail9;
+ if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
+ goto fail10;
#endif
#if EFSYS_OPT_LOOPBACK
- if ((rc = siena_loopback_cfg(enp)) != 0)
- goto fail10;
+ if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
+ goto fail11;
#endif
#if EFSYS_OPT_MON_STATS
- if ((rc = siena_monitor_cfg(enp)) != 0)
- goto fail11;
+ if ((rc = mcdi_mon_cfg_build(enp)) != 0)
+ goto fail12;
#endif
encp->enc_features = enp->en_features;
@@ -667,21 +284,23 @@ siena_nic_probe(
return (0);
#if EFSYS_OPT_MON_STATS
+fail12:
+ EFSYS_PROBE(fail12);
+#endif
+#if EFSYS_OPT_LOOPBACK
fail11:
EFSYS_PROBE(fail11);
#endif
-#if EFSYS_OPT_LOOPBACK
+#if EFSYS_OPT_MAC_STATS
fail10:
EFSYS_PROBE(fail10);
#endif
-#if EFSYS_OPT_MAC_STATS
+#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
fail9:
EFSYS_PROBE(fail9);
#endif
-#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
fail8:
EFSYS_PROBE(fail8);
-#endif
fail7:
EFSYS_PROBE(fail7);
fail6:
@@ -710,16 +329,20 @@ siena_nic_reset(
EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
/* siena_nic_reset() is called to recover from BADASSERT failures. */
- if ((rc = siena_nic_read_assertion(enp)) != 0)
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
goto fail1;
- if ((rc = siena_nic_exit_assertion_handler(enp)) != 0)
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
goto fail2;
- req.emr_cmd = MC_CMD_PORT_RESET;
- EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_IN_LEN == 0);
+ /*
+ * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
+ * for backwards compatibility with PORT_RESET_IN_LEN.
+ */
+ EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
+
+ req.emr_cmd = MC_CMD_ENTITY_RESET;
req.emr_in_buf = NULL;
req.emr_in_length = 0;
- EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_OUT_LEN == 0);
req.emr_out_buf = NULL;
req.emr_out_length = 0;
@@ -742,40 +365,6 @@ fail1:
return (0);
}
-static __checkReturn int
-siena_nic_logging(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_LOG_CTRL_IN_LEN];
- int rc;
-
- req.emr_cmd = MC_CMD_LOG_CTRL;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_LOG_CTRL_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST,
- MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ);
- MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST_EVQ, 0);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
static void
siena_nic_rx_cfg(
__in efx_nic_t *enp)
@@ -814,7 +403,8 @@ siena_nic_init(
EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
- if ((rc = siena_nic_logging(enp)) != 0)
+ /* Enable reporting of some events (e.g. link change) */
+ if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
goto fail1;
siena_sram_init(enp);
@@ -850,12 +440,15 @@ siena_nic_fini(
siena_nic_unprobe(
__in efx_nic_t *enp)
{
- (void) siena_nic_attach(enp, B_FALSE);
+#if EFSYS_OPT_MON_STATS
+ mcdi_mon_cfg_free(enp);
+#endif /* EFSYS_OPT_MON_STATS */
+ (void) efx_mcdi_drv_attach(enp, B_FALSE);
}
#if EFSYS_OPT_DIAG
-static efx_register_set_t __cs __siena_registers[] = {
+static efx_register_set_t __siena_registers[] = {
{ FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
{ FR_CZ_USR_EV_CFG_OFST, 0, 1 },
{ FR_AZ_RX_CFG_REG_OFST, 0, 1 },
@@ -871,7 +464,7 @@ static efx_register_set_t __cs __siena_registers[] = {
{ FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
};
-static const uint32_t __cs __siena_register_masks[] = {
+static const uint32_t __siena_register_masks[] = {
0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
0x000103FF, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
@@ -887,7 +480,7 @@ static const uint32_t __cs __siena_register_masks[] = {
0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
};
-static efx_register_set_t __cs __siena_tables[] = {
+static efx_register_set_t __siena_tables[] = {
{ FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
FR_AZ_RX_FILTER_TBL0_ROWS },
{ FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
@@ -903,7 +496,7 @@ static efx_register_set_t __cs __siena_tables[] = {
FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
};
-static const uint32_t __cs __siena_table_masks[] = {
+static const uint32_t __siena_table_masks[] = {
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
diff --git a/sys/dev/sfxge/common/siena_nvram.c b/sys/dev/sfxge/common/siena_nvram.c
index fa746ab269db..7d20ec0f36e1 100644
--- a/sys/dev/sfxge/common/siena_nvram.c
+++ b/sys/dev/sfxge/common/siena_nvram.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -42,9 +47,6 @@ siena_nvram_partn_size(
__in unsigned int partn,
__out size_t *sizep)
{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
- MC_CMD_NVRAM_INFO_OUT_LEN)];
int rc;
if ((1 << partn) & ~enp->en_u.siena.enu_partn_mask) {
@@ -52,32 +54,12 @@ siena_nvram_partn_size(
goto fail1;
}
- req.emr_cmd = MC_CMD_NVRAM_INFO;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_NVRAM_INFO_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_info(enp, partn, sizep, NULL, NULL)) != 0) {
goto fail2;
}
- if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail3;
- }
-
- *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
-
return (0);
-fail3:
- EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
@@ -91,23 +73,9 @@ siena_nvram_partn_lock(
__in efx_nic_t *enp,
__in unsigned int partn)
{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_NVRAM_UPDATE_START_IN_LEN];
int rc;
- req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_UPDATE_START_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_update_start(enp, partn)) != 0) {
goto fail1;
}
@@ -127,43 +95,17 @@ siena_nvram_partn_read(
__out_bcount(size) caddr_t data,
__in size_t size)
{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_LEN,
- MC_CMD_NVRAM_READ_OUT_LEN(SIENA_NVRAM_CHUNK))];
size_t chunk;
int rc;
while (size > 0) {
chunk = MIN(size, SIENA_NVRAM_CHUNK);
- req.emr_cmd = MC_CMD_NVRAM_READ;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_READ_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length =
- MC_CMD_NVRAM_READ_OUT_LEN(SIENA_NVRAM_CHUNK);
-
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_OFFSET, offset);
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_LENGTH, chunk);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_read(enp, partn, offset,
+ data, chunk)) != 0) {
goto fail1;
}
- if (req.emr_out_length_used <
- MC_CMD_NVRAM_READ_OUT_LEN(chunk)) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- memcpy(data,
- MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
- chunk);
-
size -= chunk;
data += chunk;
offset += chunk;
@@ -171,8 +113,6 @@ siena_nvram_partn_read(
return (0);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
@@ -186,25 +126,9 @@ siena_nvram_partn_erase(
__in unsigned int offset,
__in size_t size)
{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_NVRAM_ERASE_IN_LEN];
int rc;
- req.emr_cmd = MC_CMD_NVRAM_ERASE;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_ERASE_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
- MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_erase(enp, partn, offset, size)) != 0) {
goto fail1;
}
@@ -224,32 +148,14 @@ siena_nvram_partn_write(
__out_bcount(size) caddr_t data,
__in size_t size)
{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_NVRAM_WRITE_IN_LEN(SIENA_NVRAM_CHUNK)];
size_t chunk;
int rc;
while (size > 0) {
chunk = MIN(size, SIENA_NVRAM_CHUNK);
- req.emr_cmd = MC_CMD_NVRAM_WRITE;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(chunk);
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_WRITE_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
- MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, chunk);
-
- memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
- data, chunk);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_write(enp, partn, offset,
+ data, chunk)) != 0) {
goto fail1;
}
@@ -271,18 +177,9 @@ siena_nvram_partn_unlock(
__in efx_nic_t *enp,
__in unsigned int partn)
{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN];
- uint32_t reboot;
+ boolean_t reboot;
int rc;
- req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
/*
* Reboot into the new image only for PHYs. The driver has to
* explicitly cope with an MC reboot after a firmware update.
@@ -291,13 +188,7 @@ siena_nvram_partn_unlock(
partn == MC_CMD_NVRAM_TYPE_PHY_PORT1 ||
partn == MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO);
- MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_update_finish(enp, partn, reboot)) != 0) {
goto fail1;
}
@@ -338,7 +229,6 @@ static siena_parttbl_entry_t siena_parttbl[] = {
{MC_CMD_NVRAM_TYPE_FC_FW, 2, EFX_NVRAM_FCFW},
{MC_CMD_NVRAM_TYPE_CPLD, 1, EFX_NVRAM_CPLD},
{MC_CMD_NVRAM_TYPE_CPLD, 2, EFX_NVRAM_CPLD},
- {0, 0, 0},
};
static __checkReturn siena_parttbl_entry_t *
@@ -346,12 +236,15 @@ siena_parttbl_entry(
__in efx_nic_t *enp,
__in efx_nvram_type_t type)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
siena_parttbl_entry_t *entry;
+ unsigned int i;
EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
- for (entry = siena_parttbl; entry->port > 0; ++entry) {
+ for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
+ entry = &siena_parttbl[i];
+
if (entry->port == emip->emi_port && entry->nvtype == type)
return (entry);
}
@@ -365,59 +258,29 @@ siena_parttbl_entry(
siena_nvram_test(
__in efx_nic_t *enp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
siena_parttbl_entry_t *entry;
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
- MC_CMD_NVRAM_TEST_OUT_LEN)];
- int result;
+ unsigned int i;
int rc;
- req.emr_cmd = MC_CMD_NVRAM_TEST;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
-
/*
* Iterate over the list of supported partition types
* applicable to *this* port
*/
- for (entry = siena_parttbl; entry->port > 0; ++entry) {
+ for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
+ entry = &siena_parttbl[i];
+
if (entry->port != emip->emi_port ||
!(enp->en_u.siena.enu_partn_mask & (1 << entry->partn)))
continue;
- MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, entry->partn);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_test(enp, entry->partn)) != 0) {
goto fail1;
}
-
- if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
- if (result == MC_CMD_NVRAM_TEST_FAIL) {
-
- EFSYS_PROBE1(nvram_test_failure, int, entry->partn);
-
- rc = (EINVAL);
- goto fail3;
- }
}
return (0);
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
@@ -467,7 +330,7 @@ siena_nvram_get_dynamic_cfg(
__out siena_mc_dynamic_config_hdr_t **dcfgp,
__out size_t *sizep)
{
- siena_mc_dynamic_config_hdr_t *dcfg;
+ siena_mc_dynamic_config_hdr_t *dcfg = NULL;
size_t size;
uint8_t cksum;
unsigned int vpd_offset;
@@ -577,34 +440,35 @@ fail4:
EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
EFSYS_KMEM_FREE(enp->en_esip, size, dcfg);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
return (rc);
}
-static __checkReturn int
+ __checkReturn int
siena_nvram_get_subtype(
__in efx_nic_t *enp,
__in unsigned int partn,
__out uint32_t *subtypep)
{
efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMAX];
+ uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
+ MC_CMD_GET_BOARD_CFG_OUT_LENMAX)];
efx_word_t *fw_list;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_BOARD_CFG;
- EFX_STATIC_ASSERT(MC_CMD_GET_BOARD_CFG_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_BOARD_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LENMAX;
efx_mcdi_execute(enp, &req);
@@ -652,6 +516,7 @@ siena_nvram_get_version(
siena_parttbl_entry_t *entry;
unsigned int dcfg_partn;
unsigned int partn;
+ unsigned int i;
int rc;
if ((entry = siena_parttbl_entry(enp, type)) == NULL) {
@@ -674,11 +539,12 @@ siena_nvram_get_version(
* that have access to this partition.
*/
version[0] = version[1] = version[2] = version[3] = 0;
- for (entry = siena_parttbl; entry->port > 0; ++entry) {
+ for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
unsigned int nitems;
uint16_t temp[4];
size_t length;
+ entry = &siena_parttbl[i];
if (entry->partn != partn)
continue;
@@ -869,7 +735,7 @@ siena_nvram_rw_finish(
siena_nvram_set_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint16_t version[4])
+ __in_ecount(4) uint16_t version[4])
{
siena_mc_dynamic_config_hdr_t *dcfg = NULL;
siena_parttbl_entry_t *entry;
diff --git a/sys/dev/sfxge/common/siena_phy.c b/sys/dev/sfxge/common/siena_phy.c
index 31b5c4637f83..fd0871dd98c8 100644
--- a/sys/dev/sfxge/common/siena_phy.c
+++ b/sys/dev/sfxge/common/siena_phy.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -192,15 +197,16 @@ siena_phy_get_link(
__out siena_link_state_t *slsp)
{
efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_LINK_OUT_LEN];
+ uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
+ MC_CMD_GET_LINK_OUT_LEN)];
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_LINK;
- EFX_STATIC_ASSERT(MC_CMD_GET_LINK_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;
efx_mcdi_execute(enp, &req);
@@ -266,19 +272,21 @@ siena_phy_reconfigure(
{
efx_port_t *epp = &(enp->en_port);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SET_ID_LED_IN_LEN,
- MC_CMD_SET_LINK_IN_LEN)];
+ uint8_t payload[MAX(MAX(MC_CMD_SET_ID_LED_IN_LEN,
+ MC_CMD_SET_ID_LED_OUT_LEN),
+ MAX(MC_CMD_SET_LINK_IN_LEN,
+ MC_CMD_SET_LINK_OUT_LEN))];
uint32_t cap_mask;
unsigned int led_mode;
unsigned int speed;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_LINK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_SET_LINK_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_LINK_OUT_LEN;
cap_mask = epp->ep_adv_cap_mask;
MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP,
@@ -329,12 +337,12 @@ siena_phy_reconfigure(
}
/* And set the blink mode */
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_ID_LED;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_SET_ID_LED_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;
#if EFSYS_OPT_PHY_LED_CONTROL
switch (epp->ep_phy_led_mode) {
@@ -379,16 +387,17 @@ siena_phy_verify(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_PHY_STATE_OUT_LEN];
+ uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
+ MC_CMD_GET_PHY_STATE_OUT_LEN)];
uint32_t state;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PHY_STATE;
- EFX_STATIC_ASSERT(MC_CMD_GET_PHY_STATE_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN;
efx_mcdi_execute(enp, &req);
@@ -544,18 +553,19 @@ siena_phy_stats_update(
__out_ecount(EFX_PHY_NSTATS) uint32_t *stat)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t vmask = encp->enc_siena_phy_stat_mask;
- uint8_t payload[MC_CMD_PHY_STATS_IN_LEN];
+ uint32_t vmask = encp->enc_mcdi_phy_stat_mask;
uint64_t smask;
efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_PHY_STATS_IN_LEN,
+ MC_CMD_PHY_STATS_OUT_DMA_LEN)];
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_PHY_STATS;
req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_PHY_STATS_OUT_DMA_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_in_length = MC_CMD_PHY_STATS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_PHY_STATS_OUT_DMA_LEN;
MCDI_IN_SET_DWORD(req, PHY_STATS_IN_DMA_ADDR_LO,
EFSYS_MEM_ADDR(esmp) & 0xffffffff);
@@ -587,7 +597,7 @@ fail1:
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
siena_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -624,46 +634,17 @@ siena_phy_prop_set(
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
__checkReturn int
siena_phy_bist_start(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type)
+ __in efx_bist_type_t type)
{
- uint8_t payload[MC_CMD_START_BIST_IN_LEN];
- efx_mcdi_req_t req;
int rc;
- req.emr_cmd = MC_CMD_START_BIST;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_START_BIST_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- switch (type) {
- case EFX_PHY_BIST_TYPE_NORMAL:
- MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE, MC_CMD_PHY_BIST);
- break;
- case EFX_PHY_BIST_TYPE_CABLE_SHORT:
- MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
- MC_CMD_PHY_BIST_CABLE_SHORT);
- break;
- case EFX_PHY_BIST_TYPE_CABLE_LONG:
- MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
- MC_CMD_PHY_BIST_CABLE_LONG);
- break;
- default:
- EFSYS_ASSERT(0);
- }
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_bist_start(enp, type)) != 0)
goto fail1;
- }
return (0);
@@ -696,8 +677,8 @@ siena_phy_sft9001_bist_status(
__checkReturn int
siena_phy_bist_poll(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type,
- __out efx_phy_bist_result_t *resultp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
__out_opt __drv_when(count > 0, __notnull)
uint32_t *value_maskp,
__out_ecount_opt(count) __drv_when(count > 0, __notnull)
@@ -705,19 +686,19 @@ siena_phy_bist_poll(
__in size_t count)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint8_t payload[MCDI_CTL_SDU_LEN_MAX];
+ uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
+ MCDI_CTL_SDU_LEN_MAX)];
uint32_t value_mask = 0;
efx_mcdi_req_t req;
uint32_t result;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_POLL_BIST;
- _NOTE(CONSTANTCONDITION)
- EFSYS_ASSERT(MC_CMD_POLL_BIST_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
req.emr_out_buf = payload;
- req.emr_out_length = sizeof (payload);
+ req.emr_out_length = MCDI_CTL_SDU_LEN_MAX;
efx_mcdi_execute(enp, &req);
@@ -740,90 +721,90 @@ siena_phy_bist_poll(
if (result == MC_CMD_POLL_BIST_PASSED &&
encp->enc_phy_type == EFX_PHY_SFT9001B &&
req.emr_out_length_used >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN &&
- (type == EFX_PHY_BIST_TYPE_CABLE_SHORT ||
- type == EFX_PHY_BIST_TYPE_CABLE_LONG)) {
+ (type == EFX_BIST_TYPE_PHY_CABLE_SHORT ||
+ type == EFX_BIST_TYPE_PHY_CABLE_LONG)) {
uint16_t word;
- if (count > EFX_PHY_BIST_CABLE_LENGTH_A) {
+ if (count > EFX_BIST_PHY_CABLE_LENGTH_A) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_CABLE_LENGTH_A] =
+ valuesp[EFX_BIST_PHY_CABLE_LENGTH_A] =
MCDI_OUT_DWORD(req,
POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
- value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_A);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_A);
}
- if (count > EFX_PHY_BIST_CABLE_LENGTH_B) {
+ if (count > EFX_BIST_PHY_CABLE_LENGTH_B) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_CABLE_LENGTH_B] =
+ valuesp[EFX_BIST_PHY_CABLE_LENGTH_B] =
MCDI_OUT_DWORD(req,
POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B);
- value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_B);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_B);
}
- if (count > EFX_PHY_BIST_CABLE_LENGTH_C) {
+ if (count > EFX_BIST_PHY_CABLE_LENGTH_C) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_CABLE_LENGTH_C] =
+ valuesp[EFX_BIST_PHY_CABLE_LENGTH_C] =
MCDI_OUT_DWORD(req,
POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C);
- value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_C);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_C);
}
- if (count > EFX_PHY_BIST_CABLE_LENGTH_D) {
+ if (count > EFX_BIST_PHY_CABLE_LENGTH_D) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_CABLE_LENGTH_D] =
+ valuesp[EFX_BIST_PHY_CABLE_LENGTH_D] =
MCDI_OUT_DWORD(req,
POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D);
- value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_D);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_D);
}
- if (count > EFX_PHY_BIST_CABLE_STATUS_A) {
+ if (count > EFX_BIST_PHY_CABLE_STATUS_A) {
if (valuesp != NULL) {
word = MCDI_OUT_WORD(req,
POLL_BIST_OUT_SFT9001_CABLE_STATUS_A);
- valuesp[EFX_PHY_BIST_CABLE_STATUS_A] =
+ valuesp[EFX_BIST_PHY_CABLE_STATUS_A] =
siena_phy_sft9001_bist_status(word);
}
- value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_A);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_A);
}
- if (count > EFX_PHY_BIST_CABLE_STATUS_B) {
+ if (count > EFX_BIST_PHY_CABLE_STATUS_B) {
if (valuesp != NULL) {
word = MCDI_OUT_WORD(req,
POLL_BIST_OUT_SFT9001_CABLE_STATUS_B);
- valuesp[EFX_PHY_BIST_CABLE_STATUS_B] =
+ valuesp[EFX_BIST_PHY_CABLE_STATUS_B] =
siena_phy_sft9001_bist_status(word);
}
- value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_B);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_B);
}
- if (count > EFX_PHY_BIST_CABLE_STATUS_C) {
+ if (count > EFX_BIST_PHY_CABLE_STATUS_C) {
if (valuesp != NULL) {
word = MCDI_OUT_WORD(req,
POLL_BIST_OUT_SFT9001_CABLE_STATUS_C);
- valuesp[EFX_PHY_BIST_CABLE_STATUS_C] =
+ valuesp[EFX_BIST_PHY_CABLE_STATUS_C] =
siena_phy_sft9001_bist_status(word);
}
- value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_C);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_C);
}
- if (count > EFX_PHY_BIST_CABLE_STATUS_D) {
+ if (count > EFX_BIST_PHY_CABLE_STATUS_D) {
if (valuesp != NULL) {
word = MCDI_OUT_WORD(req,
POLL_BIST_OUT_SFT9001_CABLE_STATUS_D);
- valuesp[EFX_PHY_BIST_CABLE_STATUS_D] =
+ valuesp[EFX_BIST_PHY_CABLE_STATUS_D] =
siena_phy_sft9001_bist_status(word);
}
- value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_D);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_D);
}
} else if (result == MC_CMD_POLL_BIST_FAILED &&
encp->enc_phy_type == EFX_PHY_QLX111V &&
req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN &&
- count > EFX_PHY_BIST_FAULT_CODE) {
+ count > EFX_BIST_FAULT_CODE) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_FAULT_CODE] =
+ valuesp[EFX_BIST_FAULT_CODE] =
MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST);
- value_mask |= 1 << EFX_PHY_BIST_FAULT_CODE;
+ value_mask |= 1 << EFX_BIST_FAULT_CODE;
}
if (value_maskp != NULL)
@@ -831,11 +812,11 @@ siena_phy_bist_poll(
EFSYS_ASSERT(resultp != NULL);
if (result == MC_CMD_POLL_BIST_RUNNING)
- *resultp = EFX_PHY_BIST_RESULT_RUNNING;
+ *resultp = EFX_BIST_RESULT_RUNNING;
else if (result == MC_CMD_POLL_BIST_PASSED)
- *resultp = EFX_PHY_BIST_RESULT_PASSED;
+ *resultp = EFX_BIST_RESULT_PASSED;
else
- *resultp = EFX_PHY_BIST_RESULT_FAILED;
+ *resultp = EFX_BIST_RESULT_FAILED;
return (0);
@@ -850,12 +831,12 @@ fail1:
void
siena_phy_bist_stop(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type)
+ __in efx_bist_type_t type)
{
/* There is no way to stop BIST on Siena */
_NOTE(ARGUNUSED(enp, type))
}
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
#endif /* EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/siena_sram.c b/sys/dev/sfxge/common/siena_sram.c
index 3137e5b79826..cf360673726d 100644
--- a/sys/dev/sfxge/common/siena_sram.c
+++ b/sys/dev/sfxge/common/siena_sram.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
diff --git a/sys/dev/sfxge/common/siena_vpd.c b/sys/dev/sfxge/common/siena_vpd.c
index 3f1008bcf528..4d4b825efc10 100644
--- a/sys/dev/sfxge/common/siena_vpd.c
+++ b/sys/dev/sfxge/common/siena_vpd.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 Solarflare Communications Inc.
+ * 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -141,11 +146,11 @@ fail4:
EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
EFSYS_KMEM_FREE(enp->en_esip, size, scfg);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
@@ -156,7 +161,7 @@ fail1:
siena_vpd_init(
__in efx_nic_t *enp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
caddr_t svpd = NULL;
unsigned partn;
size_t size = 0;
@@ -201,7 +206,7 @@ siena_vpd_size(
__in efx_nic_t *enp,
__out size_t *sizep)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
unsigned int partn;
int rc;
@@ -236,8 +241,8 @@ siena_vpd_read(
__out_bcount(size) caddr_t data,
__in size_t size)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- siena_mc_dynamic_config_hdr_t *dcfg;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ siena_mc_dynamic_config_hdr_t *dcfg = NULL;
unsigned int vpd_length;
unsigned int vpd_offset;
unsigned int dcfg_partn;
@@ -499,8 +504,8 @@ siena_vpd_write(
__in_bcount(size) caddr_t data,
__in size_t size)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- siena_mc_dynamic_config_hdr_t *dcfg;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ siena_mc_dynamic_config_hdr_t *dcfg = NULL;
unsigned int vpd_offset;
unsigned int dcfg_partn;
unsigned int hdr_length;
@@ -525,18 +530,18 @@ siena_vpd_write(
goto fail2;
if ((rc = siena_nvram_partn_lock(enp, dcfg_partn)) != 0)
- goto fail2;
+ goto fail3;
if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn,
B_FALSE, &dcfg, &dcfg_size)) != 0)
- goto fail3;
+ goto fail4;
hdr_length = EFX_WORD_FIELD(dcfg->length, EFX_WORD_0);
/* Allocated memory should have room for the new VPD */
if (hdr_length + vpd_length > dcfg_size) {
rc = ENOSPC;
- goto fail3;
+ goto fail5;
}
/* Copy in new vpd and update header */
@@ -553,12 +558,12 @@ siena_vpd_write(
/* Erase and write the new sector */
if ((rc = siena_nvram_partn_erase(enp, dcfg_partn, 0, partn_size)) != 0)
- goto fail4;
+ goto fail6;
/* Write out the new structure to nvram */
if ((rc = siena_nvram_partn_write(enp, dcfg_partn, 0, (caddr_t)dcfg,
vpd_offset + vpd_length)) != 0)
- goto fail5;
+ goto fail7;
EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
@@ -566,18 +571,22 @@ siena_vpd_write(
return (0);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
fail5:
EFSYS_PROBE(fail5);
+
+ EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
fail4:
EFSYS_PROBE(fail4);
+
+ siena_nvram_partn_unlock(enp, dcfg_partn);
fail3:
EFSYS_PROBE(fail3);
-
- EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
fail2:
EFSYS_PROBE(fail2);
-
- siena_nvram_partn_unlock(enp, dcfg_partn);
fail1:
EFSYS_PROBE1(fail1, int, rc);
diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c
index 150df724ba8c..f484b743b310 100644
--- a/sys/dev/sfxge/sfxge.c
+++ b/sys/dev/sfxge/sfxge.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -42,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/taskqueue.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
+#include <sys/priv.h>
#include <sys/syslog.h>
#include <dev/pci/pcireg.h>
@@ -57,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include "sfxge.h"
#include "sfxge_rx.h"
+#include "sfxge_ioc.h"
#include "sfxge_version.h"
#define SFXGE_CAP (IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM | \
@@ -93,6 +99,83 @@ static void
sfxge_reset(void *arg, int npending);
static int
+sfxge_estimate_rsrc_limits(struct sfxge_softc *sc)
+{
+ efx_drv_limits_t limits;
+ int rc;
+ unsigned int evq_max;
+ uint32_t evq_allocated;
+ uint32_t rxq_allocated;
+ uint32_t txq_allocated;
+
+ /*
+ * Limit the number of event queues to:
+ * - number of CPUs
+ * - hardwire maximum RSS channels
+ * - administratively specified maximum RSS channels
+ */
+ evq_max = MIN(mp_ncpus, EFX_MAXRSS);
+ if (sc->max_rss_channels > 0)
+ evq_max = MIN(evq_max, sc->max_rss_channels);
+
+ memset(&limits, 0, sizeof(limits));
+
+ limits.edl_min_evq_count = 1;
+ limits.edl_max_evq_count = evq_max;
+ limits.edl_min_txq_count = SFXGE_TXQ_NTYPES;
+ limits.edl_max_txq_count = evq_max + SFXGE_TXQ_NTYPES - 1;
+ limits.edl_min_rxq_count = 1;
+ limits.edl_max_rxq_count = evq_max;
+
+ efx_nic_set_drv_limits(sc->enp, &limits);
+
+ if ((rc = efx_nic_init(sc->enp)) != 0)
+ return (rc);
+
+ rc = efx_nic_get_vi_pool(sc->enp, &evq_allocated, &rxq_allocated,
+ &txq_allocated);
+ if (rc != 0) {
+ efx_nic_fini(sc->enp);
+ return (rc);
+ }
+
+ KASSERT(txq_allocated >= SFXGE_TXQ_NTYPES,
+ ("txq_allocated < SFXGE_TXQ_NTYPES"));
+
+ sc->evq_max = MIN(evq_allocated, evq_max);
+ sc->evq_max = MIN(rxq_allocated, sc->evq_max);
+ sc->evq_max = MIN(txq_allocated - (SFXGE_TXQ_NTYPES - 1),
+ sc->evq_max);
+
+ KASSERT(sc->evq_max <= evq_max,
+ ("allocated more than maximum requested"));
+
+ /*
+ * NIC is kept initialized in the case of success to be able to
+ * initialize port to find out media types.
+ */
+ return (0);
+}
+
+static int
+sfxge_set_drv_limits(struct sfxge_softc *sc)
+{
+ efx_drv_limits_t limits;
+
+ memset(&limits, 0, sizeof(limits));
+
+ /* Limits are strict since take into account initial estimation */
+ limits.edl_min_evq_count = limits.edl_max_evq_count =
+ sc->intr.n_alloc;
+ limits.edl_min_txq_count = limits.edl_max_txq_count =
+ sc->intr.n_alloc + SFXGE_TXQ_NTYPES - 1;
+ limits.edl_min_rxq_count = limits.edl_max_rxq_count =
+ sc->intr.n_alloc;
+
+ return (efx_nic_set_drv_limits(sc->enp, &limits));
+}
+
+static int
sfxge_start(struct sfxge_softc *sc)
{
int rc;
@@ -107,6 +190,10 @@ sfxge_start(struct sfxge_softc *sc)
goto fail;
}
+ /* Set required resource limits */
+ if ((rc = sfxge_set_drv_limits(sc)) != 0)
+ goto fail;
+
if ((rc = efx_nic_init(sc->enp)) != 0)
goto fail;
@@ -118,16 +205,16 @@ sfxge_start(struct sfxge_softc *sc)
if ((rc = sfxge_ev_start(sc)) != 0)
goto fail3;
+ /* Fire up the port. */
+ if ((rc = sfxge_port_start(sc)) != 0)
+ goto fail4;
+
/* Start the receiver side. */
if ((rc = sfxge_rx_start(sc)) != 0)
- goto fail4;
+ goto fail5;
/* Start the transmitter side. */
if ((rc = sfxge_tx_start(sc)) != 0)
- goto fail5;
-
- /* Fire up the port. */
- if ((rc = sfxge_port_start(sc)) != 0)
goto fail6;
sc->init_state = SFXGE_STARTED;
@@ -139,10 +226,10 @@ sfxge_start(struct sfxge_softc *sc)
return (0);
fail6:
- sfxge_tx_stop(sc);
+ sfxge_rx_stop(sc);
fail5:
- sfxge_rx_stop(sc);
+ sfxge_port_stop(sc);
fail4:
sfxge_ev_stop(sc);
@@ -181,15 +268,15 @@ sfxge_stop(struct sfxge_softc *sc)
sc->init_state = SFXGE_REGISTERED;
- /* Stop the port. */
- sfxge_port_stop(sc);
-
/* Stop the transmitter. */
sfxge_tx_stop(sc);
/* Stop the receiver. */
sfxge_rx_stop(sc);
+ /* Stop the port. */
+ sfxge_port_stop(sc);
+
/* Stop processing events. */
sfxge_ev_stop(sc);
@@ -201,11 +288,73 @@ sfxge_stop(struct sfxge_softc *sc)
sc->ifnet->if_drv_flags &= ~IFF_DRV_RUNNING;
}
+
+static int
+sfxge_vpd_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ioc)
+{
+ efx_vpd_value_t value;
+ int rc = 0;
+
+ switch (ioc->u.vpd.op) {
+ case SFXGE_VPD_OP_GET_KEYWORD:
+ value.evv_tag = ioc->u.vpd.tag;
+ value.evv_keyword = ioc->u.vpd.keyword;
+ rc = efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value);
+ if (rc != 0)
+ break;
+ ioc->u.vpd.len = MIN(ioc->u.vpd.len, value.evv_length);
+ if (ioc->u.vpd.payload != 0) {
+ rc = copyout(value.evv_value, ioc->u.vpd.payload,
+ ioc->u.vpd.len);
+ }
+ break;
+ case SFXGE_VPD_OP_SET_KEYWORD:
+ if (ioc->u.vpd.len > sizeof(value.evv_value))
+ return (EINVAL);
+ value.evv_tag = ioc->u.vpd.tag;
+ value.evv_keyword = ioc->u.vpd.keyword;
+ value.evv_length = ioc->u.vpd.len;
+ rc = copyin(ioc->u.vpd.payload, value.evv_value, value.evv_length);
+ if (rc != 0)
+ break;
+ rc = efx_vpd_set(sc->enp, sc->vpd_data, sc->vpd_size, &value);
+ if (rc != 0)
+ break;
+ rc = efx_vpd_verify(sc->enp, sc->vpd_data, sc->vpd_size);
+ if (rc != 0)
+ break;
+ rc = efx_vpd_write(sc->enp, sc->vpd_data, sc->vpd_size);
+ break;
+ default:
+ rc = EOPNOTSUPP;
+ break;
+ }
+
+ return (rc);
+}
+
+static int
+sfxge_private_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ioc)
+{
+ switch (ioc->op) {
+ case SFXGE_MCDI_IOC:
+ return (sfxge_mcdi_ioctl(sc, ioc));
+ case SFXGE_NVRAM_IOC:
+ return (sfxge_nvram_ioctl(sc, ioc));
+ case SFXGE_VPD_IOC:
+ return (sfxge_vpd_ioctl(sc, ioc));
+ default:
+ return (EOPNOTSUPP);
+ }
+}
+
+
static int
sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
{
struct sfxge_softc *sc;
struct ifreq *ifr;
+ sfxge_ioc_t ioc;
int error;
ifr = (struct ifreq *)data;
@@ -274,7 +423,8 @@ sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
* can't (yet) disable.
*/
KASSERT((reqcap & ~ifp->if_capabilities) == 0,
- ("Unsupported capabilities %x requested %x vs %x",
+ ("Unsupported capabilities 0x%x requested 0x%x vs "
+ "supported 0x%x",
reqcap & ~ifp->if_capabilities,
reqcap , ifp->if_capabilities));
if (capchg_mask & SFXGE_CAP_FIXED) {
@@ -337,6 +487,18 @@ sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
case SIOCGIFMEDIA:
error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
break;
+ case SIOCGPRIVATE_0:
+ error = priv_check(curthread, PRIV_DRIVER);
+ if (error != 0)
+ break;
+ error = copyin(ifr->ifr_data, &ioc, sizeof(ioc));
+ if (error != 0)
+ return (error);
+ error = sfxge_private_ioctl(sc, &ioc);
+ if (error == 0) {
+ error = copyout(&ioc, ifr->ifr_data, sizeof(ioc));
+ }
+ break;
default:
error = ether_ioctl(ifp, command, data);
}
@@ -382,6 +544,10 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
ifp->if_capenable |= IFCAP_LRO;
#endif
+ if (encp->enc_hw_tx_insert_vlan_enabled) {
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
+ ifp->if_capenable |= IFCAP_VLAN_HWTAGGING;
+ }
ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO |
CSUM_TCP_IPV6 | CSUM_UDP_IPV6;
@@ -392,6 +558,7 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
ifp->if_get_counter = sfxge_get_counter;
+ DBGPRINT(sc->dev, "ifmedia_init");
if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
goto fail;
@@ -475,10 +642,12 @@ sfxge_create(struct sfxge_softc *sc)
(void) pci_enable_busmaster(dev);
/* Initialize DMA mappings. */
+ DBGPRINT(sc->dev, "dma_init...");
if ((error = sfxge_dma_init(sc)) != 0)
goto fail;
/* Map the device registers. */
+ DBGPRINT(sc->dev, "bar_init...");
if ((error = sfxge_bar_init(sc)) != 0)
goto fail;
@@ -486,6 +655,8 @@ sfxge_create(struct sfxge_softc *sc)
&sc->family);
KASSERT(error == 0, ("Family should be filtered by sfxge_probe()"));
+ DBGPRINT(sc->dev, "nic_create...");
+
/* Create the common code nic object. */
SFXGE_EFSYS_LOCK_INIT(&sc->enp_lock,
device_get_nameunit(sc->dev), "nic");
@@ -495,7 +666,8 @@ sfxge_create(struct sfxge_softc *sc)
sc->enp = enp;
if (!ISP2(sfxge_rx_ring_entries) ||
- !(sfxge_rx_ring_entries & EFX_RXQ_NDESCS_MASK)) {
+ (sfxge_rx_ring_entries < EFX_RXQ_MINNDESCS) ||
+ (sfxge_rx_ring_entries > EFX_RXQ_MAXNDESCS)) {
log(LOG_ERR, "%s=%d must be power of 2 from %u to %u",
SFXGE_PARAM_RX_RING, sfxge_rx_ring_entries,
EFX_RXQ_MINNDESCS, EFX_RXQ_MAXNDESCS);
@@ -505,20 +677,23 @@ sfxge_create(struct sfxge_softc *sc)
sc->rxq_entries = sfxge_rx_ring_entries;
if (!ISP2(sfxge_tx_ring_entries) ||
- !(sfxge_tx_ring_entries & EFX_TXQ_NDESCS_MASK)) {
+ (sfxge_tx_ring_entries < EFX_TXQ_MINNDESCS) ||
+ (sfxge_tx_ring_entries > EFX_TXQ_MAXNDESCS(efx_nic_cfg_get(enp)))) {
log(LOG_ERR, "%s=%d must be power of 2 from %u to %u",
SFXGE_PARAM_TX_RING, sfxge_tx_ring_entries,
- EFX_TXQ_MINNDESCS, EFX_TXQ_MAXNDESCS);
+ EFX_TXQ_MINNDESCS, EFX_TXQ_MAXNDESCS(efx_nic_cfg_get(enp)));
error = EINVAL;
goto fail_tx_ring_entries;
}
sc->txq_entries = sfxge_tx_ring_entries;
/* Initialize MCDI to talk to the microcontroller. */
+ DBGPRINT(sc->dev, "mcdi_init...");
if ((error = sfxge_mcdi_init(sc)) != 0)
goto fail4;
/* Probe the NIC and build the configuration data area. */
+ DBGPRINT(sc->dev, "nic_probe...");
if ((error = efx_nic_probe(enp)) != 0)
goto fail5;
@@ -528,50 +703,75 @@ sfxge_create(struct sfxge_softc *sc)
SFXGE_VERSION_STRING, 0,
"Driver version");
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "phy_type", CTLFLAG_RD,
+ NULL, efx_nic_cfg_get(enp)->enc_phy_type,
+ "PHY type");
+
/* Initialize the NVRAM. */
+ DBGPRINT(sc->dev, "nvram_init...");
if ((error = efx_nvram_init(enp)) != 0)
goto fail6;
/* Initialize the VPD. */
+ DBGPRINT(sc->dev, "vpd_init...");
if ((error = efx_vpd_init(enp)) != 0)
goto fail7;
+ efx_mcdi_new_epoch(enp);
+
/* Reset the NIC. */
+ DBGPRINT(sc->dev, "nic_reset...");
if ((error = efx_nic_reset(enp)) != 0)
goto fail8;
/* Initialize buffer table allocation. */
sc->buffer_table_next = 0;
+ /*
+ * Guarantee minimum and estimate maximum number of event queues
+ * to take it into account when MSI-X interrupts are allocated.
+ * It initializes NIC and keeps it initialized on success.
+ */
+ if ((error = sfxge_estimate_rsrc_limits(sc)) != 0)
+ goto fail8;
+
/* Set up interrupts. */
+ DBGPRINT(sc->dev, "intr_init...");
if ((error = sfxge_intr_init(sc)) != 0)
- goto fail8;
+ goto fail9;
/* Initialize event processing state. */
+ DBGPRINT(sc->dev, "ev_init...");
if ((error = sfxge_ev_init(sc)) != 0)
goto fail11;
+ /* Initialize port state. */
+ DBGPRINT(sc->dev, "port_init...");
+ if ((error = sfxge_port_init(sc)) != 0)
+ goto fail12;
+
/* Initialize receive state. */
+ DBGPRINT(sc->dev, "rx_init...");
if ((error = sfxge_rx_init(sc)) != 0)
- goto fail12;
+ goto fail13;
/* Initialize transmit state. */
+ DBGPRINT(sc->dev, "tx_init...");
if ((error = sfxge_tx_init(sc)) != 0)
- goto fail13;
-
- /* Initialize port state. */
- if ((error = sfxge_port_init(sc)) != 0)
goto fail14;
sc->init_state = SFXGE_INITIALIZED;
+ DBGPRINT(sc->dev, "success");
return (0);
fail14:
- sfxge_tx_fini(sc);
+ sfxge_rx_fini(sc);
fail13:
- sfxge_rx_fini(sc);
+ sfxge_port_fini(sc);
fail12:
sfxge_ev_fini(sc);
@@ -579,6 +779,9 @@ fail12:
fail11:
sfxge_intr_fini(sc);
+fail9:
+ efx_nic_fini(sc->enp);
+
fail8:
efx_vpd_fini(enp);
@@ -603,6 +806,7 @@ fail3:
(void) pci_disable_busmaster(sc->dev);
fail:
+ DBGPRINT(sc->dev, "failed %d", error);
sc->dev = NULL;
SFXGE_ADAPTER_LOCK_DESTROY(sc);
return (error);
@@ -613,15 +817,15 @@ sfxge_destroy(struct sfxge_softc *sc)
{
efx_nic_t *enp;
- /* Clean up port state. */
- sfxge_port_fini(sc);
-
/* Clean up transmit state. */
sfxge_tx_fini(sc);
/* Clean up receive state. */
sfxge_rx_fini(sc);
+ /* Clean up port state. */
+ sfxge_port_fini(sc);
+
/* Clean up event processing state. */
sfxge_ev_fini(sc);
@@ -750,6 +954,7 @@ sfxge_reset(void *arg, int npending)
{
struct sfxge_softc *sc;
int rc;
+ unsigned attempt;
(void)npending;
@@ -762,10 +967,15 @@ sfxge_reset(void *arg, int npending)
sfxge_stop(sc);
efx_nic_reset(sc->enp);
- if ((rc = sfxge_start(sc)) != 0)
- device_printf(sc->dev,
- "reset failed (%d); interface is now stopped\n",
- rc);
+ for (attempt = 0; attempt < 3; ++attempt) {
+ if ((rc = sfxge_start(sc)) == 0)
+ goto done;
+
+ device_printf(sc->dev, "start on reset failed (%d)\n", rc);
+ DELAY(100000);
+ }
+
+ device_printf(sc->dev, "reset failed; interface is now stopped\n");
done:
SFXGE_ADAPTER_UNLOCK(sc);
@@ -797,29 +1007,42 @@ sfxge_attach(device_t dev)
sc->ifnet = ifp;
/* Initialize hardware. */
+ DBGPRINT(sc->dev, "create nic");
if ((error = sfxge_create(sc)) != 0)
goto fail2;
/* Create the ifnet for the port. */
+ DBGPRINT(sc->dev, "init ifnet");
if ((error = sfxge_ifnet_init(ifp, sc)) != 0)
goto fail3;
+ DBGPRINT(sc->dev, "init vpd");
if ((error = sfxge_vpd_init(sc)) != 0)
goto fail4;
+ /*
+ * NIC is initialized inside sfxge_create() and kept inialized
+ * to be able to initialize port to discover media types in
+ * sfxge_ifnet_init().
+ */
+ efx_nic_fini(sc->enp);
+
sc->init_state = SFXGE_REGISTERED;
+ DBGPRINT(sc->dev, "success");
return (0);
fail4:
sfxge_ifnet_fini(ifp);
fail3:
+ efx_nic_fini(sc->enp);
sfxge_destroy(sc);
fail2:
if_free(sc->ifnet);
fail:
+ DBGPRINT(sc->dev, "failed %d", error);
return (error);
}
@@ -852,13 +1075,25 @@ sfxge_probe(device_t dev)
pci_vendor_id = pci_get_vendor(dev);
pci_device_id = pci_get_device(dev);
+ DBGPRINT(dev, "PCI ID %04x:%04x", pci_vendor_id, pci_device_id);
rc = efx_family(pci_vendor_id, pci_device_id, &family);
- if (rc != 0)
+ if (rc != 0) {
+ DBGPRINT(dev, "efx_family fail %d", rc);
return (ENXIO);
+ }
- KASSERT(family == EFX_FAMILY_SIENA, ("impossible controller family"));
- device_set_desc(dev, "Solarflare SFC9000 family");
- return (0);
+ if (family == EFX_FAMILY_SIENA) {
+ device_set_desc(dev, "Solarflare SFC9000 family");
+ return (0);
+ }
+
+ if (family == EFX_FAMILY_HUNTINGTON) {
+ device_set_desc(dev, "Solarflare SFC9100 family");
+ return (0);
+ }
+
+ DBGPRINT(dev, "impossible controller family %d", family);
+ return (ENXIO);
}
static device_method_t sfxge_methods[] = {
diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h
index 20a30d053d8f..6e6c0af67de6 100644
--- a/sys/dev/sfxge/sfxge.h
+++ b/sys/dev/sfxge/sfxge.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -34,7 +38,6 @@
#include <sys/param.h>
#include <sys/kernel.h>
-#include <sys/condvar.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
@@ -46,6 +49,18 @@
#include <net/if_media.h>
#include <net/if_types.h>
+#include "sfxge_ioc.h"
+
+/*
+ * Debugging
+ */
+#if 0
+#define DBGPRINT(dev, fmt, args...) \
+ device_printf(dev, "%s: " fmt "\n", __func__, ## args)
+#else
+#define DBGPRINT(dev, fmt, args...)
+#endif
+
/*
* Backward-compatibility
*/
@@ -72,6 +87,10 @@
#define IFM_10G_KX4 IFM_10G_CX4
#endif
+#ifndef IFM_40G_CR4
+#define IFM_40G_CR4 IFM_UNKNOWN
+#endif
+
#if (__FreeBSD_version >= 800501 && __FreeBSD_version < 900000) || \
__FreeBSD_version >= 900003
#define SFXGE_HAVE_DESCRIBE_INTR
@@ -161,7 +180,7 @@ enum sfxge_mcdi_state {
struct sfxge_mcdi {
struct mtx lock;
- struct cv cv;
+ efsys_mem_t mem;
enum sfxge_mcdi_state state;
efx_mcdi_transport_t transport;
@@ -191,6 +210,9 @@ struct sfxge_port {
struct sfxge_hw_stats phy_stats;
struct sfxge_hw_stats mac_stats;
efx_link_mode_t link_mode;
+ uint8_t mcast_addrs[EFX_MAC_MULTICAST_LIST_MAX *
+ EFX_MAC_ADDR_LEN];
+ unsigned int mcast_count;
/* Only used in debugging output */
char lock_name[SFXGE_LOCK_NAME_MAX];
@@ -250,11 +272,15 @@ struct sfxge_softc {
size_t rx_prefix_size;
size_t rx_buffer_size;
+ size_t rx_buffer_align;
uma_zone_t rx_buffer_zone;
+ unsigned int evq_max;
unsigned int evq_count;
unsigned int rxq_count;
unsigned int txq_count;
+
+ int tso_fw_assisted;
};
#define SFXGE_LINK_UP(sc) ((sc)->port.link_mode != EFX_LINK_DOWN)
@@ -277,10 +303,12 @@ extern void sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n,
extern int sfxge_dma_init(struct sfxge_softc *sc);
extern void sfxge_dma_fini(struct sfxge_softc *sc);
extern int sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len,
- efsys_mem_t *esmp);
+ efsys_mem_t *esmp);
extern void sfxge_dma_free(efsys_mem_t *esmp);
extern int sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map,
- struct mbuf **mp, bus_dma_segment_t *segs, int *nsegs, int maxsegs);
+ struct mbuf **mp,
+ bus_dma_segment_t *segs,
+ int *nsegs, int maxsegs);
/*
* From sfxge_ev.c.
@@ -304,6 +332,12 @@ extern void sfxge_intr_stop(struct sfxge_softc *sc);
*/
extern int sfxge_mcdi_init(struct sfxge_softc *sc);
extern void sfxge_mcdi_fini(struct sfxge_softc *sc);
+extern int sfxge_mcdi_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip);
+
+/*
+ * From sfxge_nvram.c.
+ */
+extern int sfxge_nvram_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip);
/*
* From sfxge_port.c.
@@ -313,7 +347,7 @@ extern void sfxge_port_fini(struct sfxge_softc *sc);
extern int sfxge_port_start(struct sfxge_softc *sc);
extern void sfxge_port_stop(struct sfxge_softc *sc);
extern void sfxge_mac_link_update(struct sfxge_softc *sc,
- efx_link_mode_t mode);
+ efx_link_mode_t mode);
extern int sfxge_mac_filter_set(struct sfxge_softc *sc);
extern int sfxge_port_ifmedia_init(struct sfxge_softc *sc);
extern uint64_t sfxge_get_counter(struct ifnet *ifp, ift_counter c);
diff --git a/sys/dev/sfxge/sfxge_dma.c b/sys/dev/sfxge/sfxge_dma.c
index d1831ac68bb5..b4347c057749 100644
--- a/sys/dev/sfxge/sfxge_dma.c
+++ b/sys/dev/sfxge/sfxge_dma.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -60,7 +64,8 @@ sfxge_dma_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
int
sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map,
- struct mbuf **mp, bus_dma_segment_t *segs, int *nsegs, int maxsegs)
+ struct mbuf **mp, bus_dma_segment_t *segs,
+ int *nsegs, int maxsegs)
{
bus_dma_segment_t *psegs;
struct mbuf *m;
diff --git a/sys/dev/sfxge/sfxge_ev.c b/sys/dev/sfxge/sfxge_ev.c
index 83bdf26eea0d..4536e0af5178 100644
--- a/sys/dev/sfxge/sfxge_ev.c
+++ b/sys/dev/sfxge/sfxge_ev.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -82,12 +86,13 @@ sfxge_ev_qcomplete(struct sfxge_evq *evq, boolean_t eop)
static boolean_t
sfxge_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size,
- uint16_t flags)
+ uint16_t flags)
{
struct sfxge_evq *evq;
struct sfxge_softc *sc;
struct sfxge_rxq *rxq;
- unsigned int expected;
+ unsigned int stop;
+ unsigned int delta;
struct sfxge_rx_sw_desc *rx_desc;
evq = arg;
@@ -106,28 +111,40 @@ sfxge_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size,
if (__predict_false(rxq->init_state != SFXGE_RXQ_STARTED))
goto done;
- expected = rxq->pending++ & rxq->ptr_mask;
- if (id != expected) {
- evq->exception = B_TRUE;
+ stop = (id + 1) & rxq->ptr_mask;
+ id = rxq->pending & rxq->ptr_mask;
+ delta = (stop >= id) ? (stop - id) : (rxq->entries - id + stop);
+ rxq->pending += delta;
- device_printf(sc->dev, "RX completion out of order"
- " (id=%#x expected=%#x flags=%#x); resetting\n",
- id, expected, flags);
- sfxge_schedule_reset(sc);
+ if (delta != 1) {
+ if ((!efx_nic_cfg_get(sc->enp)->enc_rx_batching_enabled) ||
+ (delta <= 0) ||
+ (delta > efx_nic_cfg_get(sc->enp)->enc_rx_batch_max)) {
+ evq->exception = B_TRUE;
- goto done;
+ device_printf(sc->dev, "RX completion out of order"
+ " (id=%#x delta=%u flags=%#x); resetting\n",
+ id, delta, flags);
+ sfxge_schedule_reset(sc);
+
+ goto done;
+ }
}
rx_desc = &rxq->queue[id];
- KASSERT(rx_desc->flags == EFX_DISCARD,
- ("rx_desc->flags != EFX_DISCARD"));
- rx_desc->flags = flags;
-
- KASSERT(size < (1 << 16), ("size > (1 << 16)"));
- rx_desc->size = (uint16_t)size;
prefetch_read_many(rx_desc->mbuf);
+ for (; id != stop; id = (id + 1) & rxq->ptr_mask) {
+ rx_desc = &rxq->queue[id];
+ KASSERT(rx_desc->flags == EFX_DISCARD,
+ ("rx_desc->flags != EFX_DISCARD"));
+ rx_desc->flags = flags;
+
+ KASSERT(size < (1 << 16), ("size > (1 << 16)"));
+ rx_desc->size = (uint16_t)size;
+ }
+
evq->rx_done++;
if (rxq->pending - rxq->completed >= SFXGE_RX_BATCH)
@@ -148,6 +165,18 @@ sfxge_ev_exception(void *arg, uint32_t code, uint32_t data)
sc = evq->sc;
+ DBGPRINT(sc->dev, "[%d] %s", evq->index,
+ (code == EFX_EXCEPTION_RX_RECOVERY) ? "RX_RECOVERY" :
+ (code == EFX_EXCEPTION_RX_DSC_ERROR) ? "RX_DSC_ERROR" :
+ (code == EFX_EXCEPTION_TX_DSC_ERROR) ? "TX_DSC_ERROR" :
+ (code == EFX_EXCEPTION_UNKNOWN_SENSOREVT) ? "UNKNOWN_SENSOREVT" :
+ (code == EFX_EXCEPTION_FWALERT_SRAM) ? "FWALERT_SRAM" :
+ (code == EFX_EXCEPTION_UNKNOWN_FWALERT) ? "UNKNOWN_FWALERT" :
+ (code == EFX_EXCEPTION_RX_ERROR) ? "RX_ERROR" :
+ (code == EFX_EXCEPTION_TX_ERROR) ? "TX_ERROR" :
+ (code == EFX_EXCEPTION_EV_ERROR) ? "EV_ERROR" :
+ "UNKNOWN");
+
evq->exception = B_TRUE;
if (code != EFX_EXCEPTION_UNKNOWN_SENSOREVT) {
@@ -180,6 +209,11 @@ sfxge_ev_rxq_flush_done(void *arg, uint32_t rxq_index)
/* Resend a software event on the correct queue */
index = rxq->index;
+ if (index == evq->index) {
+ sfxge_rx_qflush_done(rxq);
+ return (B_FALSE);
+ }
+
evq = sc->evq[index];
label = rxq_index;
@@ -299,6 +333,11 @@ sfxge_ev_txq_flush_done(void *arg, uint32_t txq_index)
KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED,
("txq not initialized"));
+ if (txq->evq_index == evq->index) {
+ sfxge_tx_qflush_done(txq);
+ return (B_FALSE);
+ }
+
/* Resend a software event on the correct queue */
evq = sc->evq[txq->evq_index];
@@ -551,7 +590,9 @@ sfxge_ev_initialized(void *arg)
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
- KASSERT(evq->init_state == SFXGE_EVQ_STARTING,
+ /* Init done events may be duplicated on 7xxx */
+ KASSERT(evq->init_state == SFXGE_EVQ_STARTING ||
+ evq->init_state == SFXGE_EVQ_STARTED,
("evq not starting"));
evq->init_state = SFXGE_EVQ_STARTED;
diff --git a/sys/dev/sfxge/sfxge_intr.c b/sys/dev/sfxge/sfxge_intr.c
index 240a33f02b86..09538ccb8e3d 100644
--- a/sys/dev/sfxge/sfxge_intr.c
+++ b/sys/dev/sfxge/sfxge_intr.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -36,7 +40,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/rman.h>
-#include <sys/smp.h>
#include <sys/syslog.h>
#include <sys/taskqueue.h>
@@ -294,16 +297,9 @@ sfxge_intr_setup_msix(struct sfxge_softc *sc)
if (count == 0)
return (EINVAL);
- /* Limit the number of interrupts to the number of CPUs. */
- if (count > mp_ncpus)
- count = mp_ncpus;
-
- /* Not very likely these days... */
- if (count > EFX_MAXRSS)
- count = EFX_MAXRSS;
-
- if (sc->max_rss_channels > 0 && count > sc->max_rss_channels)
- count = sc->max_rss_channels;
+ /* Do not try to allocate more than already estimated EVQ maximum */
+ KASSERT(sc->evq_max > 0, ("evq_max is zero"));
+ count = MIN(count, sc->evq_max);
rid = PCIR_BAR(4);
resp = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
@@ -412,7 +408,7 @@ static const char *const __sfxge_err[] = {
void
sfxge_err(efsys_identifier_t *arg, unsigned int code, uint32_t dword0,
- uint32_t dword1)
+ uint32_t dword1)
{
struct sfxge_softc *sc = (struct sfxge_softc *)arg;
device_t dev = sc->dev;
diff --git a/sys/dev/sfxge/sfxge_ioc.h b/sys/dev/sfxge/sfxge_ioc.h
new file mode 100644
index 000000000000..bf079c87e0c9
--- /dev/null
+++ b/sys/dev/sfxge/sfxge_ioc.h
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 2014-2015 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SFXGE_IOC_H
+#define _SYS_SFXGE_IOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+/* More codes may be added if necessary */
+enum sfxge_ioc_codes {
+ SFXGE_MCDI_IOC,
+ SFXGE_NVRAM_IOC,
+ SFXGE_VPD_IOC
+};
+
+enum sfxge_nvram_ops {
+ SFXGE_NVRAM_OP_SIZE,
+ SFXGE_NVRAM_OP_READ,
+ SFXGE_NVRAM_OP_WRITE,
+ SFXGE_NVRAM_OP_ERASE,
+ SFXGE_NVRAM_OP_GET_VER,
+ SFXGE_NVRAM_OP_SET_VER
+};
+
+enum sfxge_nvram_types {
+ SFXGE_NVRAM_TYPE_BOOTROM,
+ SFXGE_NVRAM_TYPE_BOOTROM_CFG,
+ SFXGE_NVRAM_TYPE_MC,
+ SFXGE_NVRAM_TYPE_MC_GOLDEN,
+ SFXGE_NVRAM_TYPE_PHY,
+ SFXGE_NVRAM_TYPE_NULL_PHY,
+ SFXGE_NVRAM_TYPE_FPGA,
+ SFXGE_NVRAM_TYPE_FCFW,
+ SFXGE_NVRAM_TYPE_CPLD,
+ SFXGE_NVRAM_TYPE_FPGA_BACKUP,
+ SFXGE_NVRAM_TYPE_DYNAMIC_CFG
+};
+
+enum sfxge_vpd_ops {
+ SFXGE_VPD_OP_GET_KEYWORD,
+ SFXGE_VPD_OP_SET_KEYWORD
+};
+
+#define SFXGE_MCDI_MAX_PAYLOAD 0x400
+#define SFXGE_VPD_MAX_PAYLOAD 0x100
+
+typedef struct sfxge_ioc_s {
+ uint32_t op;
+ union {
+ struct {
+ caddr_t payload;
+ uint32_t cmd;
+ size_t len; /* In and out */
+ uint32_t rc;
+ } mcdi;
+ struct {
+ uint32_t op;
+ uint32_t type;
+ uint32_t offset;
+ uint32_t size;
+ uint32_t subtype;
+ uint16_t version[4]; /* get/set_ver */
+ caddr_t data;
+ } nvram;
+ struct {
+ uint8_t op;
+ uint8_t tag;
+ uint16_t keyword;
+ uint16_t len; /* In or out */
+ caddr_t payload;
+ } vpd;
+ } u;
+} __packed sfxge_ioc_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_SFXGE_IOC_H */
diff --git a/sys/dev/sfxge/sfxge_mcdi.c b/sys/dev/sfxge/sfxge_mcdi.c
index a1bc85701bd0..fb9f6500f0ad 100644
--- a/sys/dev/sfxge/sfxge_mcdi.c
+++ b/sys/dev/sfxge/sfxge_mcdi.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -37,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/syslog.h>
#include <sys/taskqueue.h>
+#include <sys/malloc.h>
#include "common/efx.h"
#include "common/efx_mcdi.h"
@@ -48,36 +53,6 @@ __FBSDID("$FreeBSD$");
#define SFXGE_MCDI_POLL_INTERVAL_MAX 100000 /* 100ms in 1us units */
#define SFXGE_MCDI_WATCHDOG_INTERVAL 10000000 /* 10s in 1us units */
-/* Acquire exclusive access to MCDI for the duration of a request. */
-static void
-sfxge_mcdi_acquire(struct sfxge_mcdi *mcdi)
-{
- SFXGE_MCDI_LOCK(mcdi);
- KASSERT(mcdi->state != SFXGE_MCDI_UNINITIALIZED,
- ("MCDI not initialized"));
-
- while (mcdi->state != SFXGE_MCDI_INITIALIZED)
- (void)cv_wait_sig(&mcdi->cv, &mcdi->lock);
- mcdi->state = SFXGE_MCDI_BUSY;
-
- SFXGE_MCDI_UNLOCK(mcdi);
-}
-
-/* Release ownership of MCDI on request completion. */
-static void
-sfxge_mcdi_release(struct sfxge_mcdi *mcdi)
-{
- SFXGE_MCDI_LOCK(mcdi);
- KASSERT((mcdi->state == SFXGE_MCDI_BUSY ||
- mcdi->state == SFXGE_MCDI_COMPLETED),
- ("MCDI not busy or task not completed"));
-
- mcdi->state = SFXGE_MCDI_INITIALIZED;
- cv_broadcast(&mcdi->cv);
-
- SFXGE_MCDI_UNLOCK(mcdi);
-}
-
static void
sfxge_mcdi_timeout(struct sfxge_softc *sc)
{
@@ -140,13 +115,16 @@ sfxge_mcdi_execute(void *arg, efx_mcdi_req_t *emrp)
sc = (struct sfxge_softc *)arg;
mcdi = &sc->mcdi;
- sfxge_mcdi_acquire(mcdi);
+ SFXGE_MCDI_LOCK(mcdi);
+
+ KASSERT(mcdi->state == SFXGE_MCDI_INITIALIZED,
+ ("MCDI not initialized"));
/* Issue request and poll for completion. */
efx_mcdi_request_start(sc->enp, emrp, B_FALSE);
sfxge_mcdi_poll(sc);
- sfxge_mcdi_release(mcdi);
+ SFXGE_MCDI_UNLOCK(mcdi);
}
static void
@@ -158,11 +136,10 @@ sfxge_mcdi_ev_cpl(void *arg)
sc = (struct sfxge_softc *)arg;
mcdi = &sc->mcdi;
- SFXGE_MCDI_LOCK(mcdi);
- KASSERT(mcdi->state == SFXGE_MCDI_BUSY, ("MCDI not busy"));
- mcdi->state = SFXGE_MCDI_COMPLETED;
- cv_broadcast(&mcdi->cv);
- SFXGE_MCDI_UNLOCK(mcdi);
+ KASSERT(mcdi->state == SFXGE_MCDI_INITIALIZED,
+ ("MCDI not initialized"));
+
+ /* We do not use MCDI completion, MCDI is simply polled */
}
static void
@@ -187,16 +164,95 @@ sfxge_mcdi_exception(void *arg, efx_mcdi_exception_t eme)
}
int
+sfxge_mcdi_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip)
+{
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
+ struct sfxge_mcdi *mp = &(sc->mcdi);
+ efx_mcdi_req_t emr;
+ uint8_t *mcdibuf;
+ int rc;
+
+ if (mp->state == SFXGE_MCDI_UNINITIALIZED) {
+ rc = ENODEV;
+ goto fail1;
+ }
+
+ if (!(encp->enc_features & EFX_FEATURE_MCDI)) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+
+ if (ip->u.mcdi.len > SFXGE_MCDI_MAX_PAYLOAD) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ mcdibuf = malloc(SFXGE_MCDI_MAX_PAYLOAD, M_TEMP, M_WAITOK | M_ZERO);
+ if (mcdibuf == NULL) {
+ rc = ENOMEM;
+ goto fail4;
+ }
+ if ((rc = copyin(ip->u.mcdi.payload, mcdibuf, ip->u.mcdi.len)) != 0) {
+ goto fail5;
+ }
+
+ emr.emr_cmd = ip->u.mcdi.cmd;
+ emr.emr_in_buf = mcdibuf;
+ emr.emr_in_length = ip->u.mcdi.len;
+
+ emr.emr_out_buf = mcdibuf;
+ emr.emr_out_length = SFXGE_MCDI_MAX_PAYLOAD;
+
+ sfxge_mcdi_execute(sc, &emr);
+
+ ip->u.mcdi.rc = emr.emr_rc;
+ ip->u.mcdi.cmd = emr.emr_cmd;
+ ip->u.mcdi.len = emr.emr_out_length_used;
+ if ((rc = copyout(mcdibuf, ip->u.mcdi.payload, ip->u.mcdi.len)) != 0) {
+ goto fail6;
+ }
+
+ /*
+ * Helpfully trigger a device reset in response to an MCDI_CMD_REBOOT
+ * Both ports will see ->emt_exception callbacks on the next MCDI poll
+ */
+ if (ip->u.mcdi.cmd == MC_CMD_REBOOT) {
+
+ EFSYS_PROBE(mcdi_ioctl_mc_reboot);
+ /* sfxge_t->s_state_lock held */
+ (void) sfxge_schedule_reset(sc);
+ }
+
+ free(mcdibuf, M_TEMP);
+
+ return (0);
+
+fail6:
+fail5:
+ free(mcdibuf, M_TEMP);
+fail4:
+fail3:
+fail2:
+fail1:
+ return (rc);
+}
+
+
+int
sfxge_mcdi_init(struct sfxge_softc *sc)
{
efx_nic_t *enp;
struct sfxge_mcdi *mcdi;
efx_mcdi_transport_t *emtp;
+ efsys_mem_t *esmp;
+ int max_msg_size;
int rc;
enp = sc->enp;
mcdi = &sc->mcdi;
emtp = &mcdi->transport;
+ esmp = &mcdi->mem;
+ max_msg_size = sizeof (uint32_t) + MCDI_CTL_SDU_LEN_MAX_V2;
KASSERT(mcdi->state == SFXGE_MCDI_UNINITIALIZED,
("MCDI already initialized"));
@@ -205,13 +261,15 @@ sfxge_mcdi_init(struct sfxge_softc *sc)
mcdi->state = SFXGE_MCDI_INITIALIZED;
+ if ((rc = sfxge_dma_alloc(sc, max_msg_size, esmp)) != 0)
+ goto fail;
+
emtp->emt_context = sc;
+ emtp->emt_dma_mem = esmp;
emtp->emt_execute = sfxge_mcdi_execute;
emtp->emt_ev_cpl = sfxge_mcdi_ev_cpl;
emtp->emt_exception = sfxge_mcdi_exception;
- cv_init(&mcdi->cv, "sfxge_mcdi");
-
if ((rc = efx_mcdi_init(enp, emtp)) != 0)
goto fail;
@@ -229,10 +287,12 @@ sfxge_mcdi_fini(struct sfxge_softc *sc)
struct sfxge_mcdi *mcdi;
efx_nic_t *enp;
efx_mcdi_transport_t *emtp;
+ efsys_mem_t *esmp;
enp = sc->enp;
mcdi = &sc->mcdi;
emtp = &mcdi->transport;
+ esmp = &mcdi->mem;
SFXGE_MCDI_LOCK(mcdi);
KASSERT(mcdi->state == SFXGE_MCDI_INITIALIZED,
@@ -241,8 +301,9 @@ sfxge_mcdi_fini(struct sfxge_softc *sc)
efx_mcdi_fini(enp);
bzero(emtp, sizeof(*emtp));
- cv_destroy(&mcdi->cv);
SFXGE_MCDI_UNLOCK(mcdi);
+ sfxge_dma_free(esmp);
+
SFXGE_MCDI_LOCK_DESTROY(mcdi);
}
diff --git a/sys/dev/sfxge/sfxge_nvram.c b/sys/dev/sfxge/sfxge_nvram.c
new file mode 100644
index 000000000000..c4fa224c53ba
--- /dev/null
+++ b/sys/dev/sfxge/sfxge_nvram.c
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2010-2015 Solarflare Communications, Inc.
+ * All rights reserved.
+ *
+ * This software was developed in part by OKTET Labs Ltd. under contract for
+ * Solarflare Communications, Inc.
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include "common/efx.h"
+#include "sfxge.h"
+
+/* These data make no real sense, they are here just to make sfupdate happy.
+ * Any code that would rely on it is broken.
+ */
+static const uint8_t fake_dynamic_cfg_nvram[] = {
+ 0x7a, 0xda, 0x10, 0xef, 0x0c, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10,
+ 0x08, 0x00, 0x00, 0x00, 0x90, 0x04, 0x00, 0x52,
+ 0x56, 0x01, 0xc3, 0x78, 0x01, 0x00, 0x03, 0x10,
+ 0x08, 0x00, 0x00, 0x00, 0x90, 0x04, 0x00, 0x52,
+ 0x56, 0x01, 0xc3, 0x78, 0x57, 0x1a, 0x10, 0xef,
+ 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x02, 0x0b, 0x64, 0x7d, 0xee, 0xee, 0xee, 0xee
+};
+
+static int
+sfxge_nvram_rw(struct sfxge_softc *sc, sfxge_ioc_t *ip, efx_nvram_type_t type,
+ boolean_t write)
+{
+ efx_nic_t *enp = sc->enp;
+ size_t total_size = ip->u.nvram.size;
+ size_t chunk_size;
+ off_t off;
+ int rc = 0;
+ uint8_t *buf;
+
+ if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA) {
+ if (write)
+ return (0);
+ rc = copyout(fake_dynamic_cfg_nvram, ip->u.nvram.data,
+ MIN(total_size, sizeof(fake_dynamic_cfg_nvram)));
+ return (rc);
+ }
+
+ if ((rc = efx_nvram_rw_start(enp, type, &chunk_size)) != 0)
+ goto fail1;
+
+ buf = malloc(chunk_size, M_TEMP, M_WAITOK);
+ if (buf == NULL) {
+ rc = ENOMEM;
+ goto fail2;
+ }
+
+ off = 0;
+ while (total_size) {
+ size_t len = MIN(chunk_size, total_size);
+
+ if (write) {
+ rc = copyin(ip->u.nvram.data + off, buf, len);
+ if (rc != 0)
+ goto fail3;
+ rc = efx_nvram_write_chunk(enp, type,
+ ip->u.nvram.offset + off, buf, len);
+ if (rc != 0)
+ goto fail3;
+ } else {
+ rc = efx_nvram_read_chunk(enp, type,
+ ip->u.nvram.offset + off, buf, len);
+ if (rc != 0)
+ goto fail3;
+ rc = copyout(buf, ip->u.nvram.data + off, len);
+ if (rc != 0)
+ goto fail3;
+ }
+
+ total_size -= len;
+ off += len;
+ }
+
+fail3:
+ free(buf, M_TEMP);
+fail2:
+ efx_nvram_rw_finish(enp, type);
+fail1:
+ return (rc);
+}
+
+
+static int
+sfxge_nvram_erase(struct sfxge_softc *sc, efx_nvram_type_t type)
+{
+ efx_nic_t *enp = sc->enp;
+ size_t chunk_size;
+ int rc = 0;
+
+ if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA)
+ return (0);
+
+ if ((rc = efx_nvram_rw_start(enp, type, &chunk_size)) != 0)
+ return (rc);
+
+ rc = efx_nvram_erase(enp, type);
+
+ efx_nvram_rw_finish(enp, type);
+ return (rc);
+}
+
+int
+sfxge_nvram_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip)
+{
+ static const efx_nvram_type_t nvram_types[] = {
+ [SFXGE_NVRAM_TYPE_BOOTROM] = EFX_NVRAM_BOOTROM,
+ [SFXGE_NVRAM_TYPE_BOOTROM_CFG] = EFX_NVRAM_BOOTROM_CFG,
+ [SFXGE_NVRAM_TYPE_MC] = EFX_NVRAM_MC_FIRMWARE,
+ [SFXGE_NVRAM_TYPE_MC_GOLDEN] = EFX_NVRAM_MC_GOLDEN,
+ [SFXGE_NVRAM_TYPE_PHY] = EFX_NVRAM_PHY,
+ [SFXGE_NVRAM_TYPE_NULL_PHY] = EFX_NVRAM_NULLPHY,
+ [SFXGE_NVRAM_TYPE_FPGA] = EFX_NVRAM_FPGA,
+ [SFXGE_NVRAM_TYPE_FCFW] = EFX_NVRAM_FCFW,
+ [SFXGE_NVRAM_TYPE_CPLD] = EFX_NVRAM_CPLD,
+ [SFXGE_NVRAM_TYPE_FPGA_BACKUP] = EFX_NVRAM_FPGA_BACKUP,
+ [SFXGE_NVRAM_TYPE_DYNAMIC_CFG] = EFX_NVRAM_DYNAMIC_CFG,
+ };
+
+ efx_nic_t *enp = sc->enp;
+ efx_nvram_type_t type;
+ int rc = 0;
+
+ if (ip->u.nvram.type > SFXGE_NVRAM_TYPE_DYNAMIC_CFG)
+ return (EINVAL);
+ type = nvram_types[ip->u.nvram.type];
+ if (type == EFX_NVRAM_MC_GOLDEN &&
+ (ip->u.nvram.op == SFXGE_NVRAM_OP_WRITE ||
+ ip->u.nvram.op == SFXGE_NVRAM_OP_ERASE ||
+ ip->u.nvram.op == SFXGE_NVRAM_OP_SET_VER))
+ return (EOPNOTSUPP);
+
+ switch (ip->u.nvram.op) {
+ case SFXGE_NVRAM_OP_SIZE:
+ {
+ size_t size;
+
+ if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA) {
+ ip->u.nvram.size = sizeof(fake_dynamic_cfg_nvram);
+ } else {
+ if ((rc = efx_nvram_size(enp, type, &size)) != 0)
+ return (rc);
+ ip->u.nvram.size = size;
+ }
+ break;
+ }
+ case SFXGE_NVRAM_OP_READ:
+ rc = sfxge_nvram_rw(sc, ip, type, B_FALSE);
+ break;
+ case SFXGE_NVRAM_OP_WRITE:
+ rc = sfxge_nvram_rw(sc, ip, type, B_TRUE);
+ break;
+ case SFXGE_NVRAM_OP_ERASE:
+ rc = sfxge_nvram_erase(sc, type);
+ break;
+ case SFXGE_NVRAM_OP_GET_VER:
+ rc = efx_nvram_get_version(enp, type, &ip->u.nvram.subtype,
+ &ip->u.nvram.version[0]);
+ break;
+ case SFXGE_NVRAM_OP_SET_VER:
+ rc = efx_nvram_set_version(enp, type, &ip->u.nvram.version[0]);
+ break;
+ default:
+ rc = EOPNOTSUPP;
+ break;
+ }
+
+ return (rc);
+}
diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c
index baddb8dcfdee..412f477254fd 100644
--- a/sys/dev/sfxge/sfxge_port.c
+++ b/sys/dev/sfxge/sfxge_port.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -70,10 +74,6 @@ sfxge_mac_stat_update(struct sfxge_softc *sc)
for (count = 0; count < 100; ++count) {
EFSYS_PROBE1(wait, unsigned int, count);
- /* Synchronize the DMA memory for reading */
- bus_dmamap_sync(esmp->esm_tag, esmp->esm_map,
- BUS_DMASYNC_POSTREAD);
-
/* Try to update the cached counters */
if ((rc = efx_mac_stats_update(sc->enp, esmp,
port->mac_stats.decode_buf, NULL)) != EAGAIN)
@@ -294,6 +294,7 @@ static const uint64_t sfxge_link_baudrate[EFX_LINK_NMODES] = {
[EFX_LINK_1000HDX] = IF_Gbps(1),
[EFX_LINK_1000FDX] = IF_Gbps(1),
[EFX_LINK_10000FDX] = IF_Gbps(10),
+ [EFX_LINK_40000FDX] = IF_Gbps(40),
};
void
@@ -342,42 +343,68 @@ done:
}
static int
-sfxge_mac_filter_set_locked(struct sfxge_softc *sc)
+sfxge_mac_multicast_list_set(struct sfxge_softc *sc)
{
- unsigned int bucket[EFX_MAC_HASH_BITS];
struct ifnet *ifp = sc->ifnet;
+ struct sfxge_port *port = &sc->port;
+ uint8_t *mcast_addr = port->mcast_addrs;
struct ifmultiaddr *ifma;
struct sockaddr_dl *sa;
- efx_nic_t *enp = sc->enp;
- unsigned int index;
- int rc;
-
- /* Set promisc-unicast and broadcast filter bits */
- if ((rc = efx_mac_filter_set(enp, !!(ifp->if_flags & IFF_PROMISC),
- B_TRUE)) != 0)
- return (rc);
-
- /* Set multicast hash filter */
- if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) {
- for (index = 0; index < EFX_MAC_HASH_BITS; index++)
- bucket[index] = 1;
- } else {
- /* Broadcast frames also go through the multicast
- * filter, and the broadcast address hashes to
- * 0xff. */
- bucket[0xff] = 1;
-
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family == AF_LINK) {
- sa = (struct sockaddr_dl *)ifma->ifma_addr;
- index = ether_crc32_le(LLADDR(sa), 6) & 0xff;
- bucket[index] = 1;
+ int rc = 0;
+
+ mtx_assert(&port->lock, MA_OWNED);
+
+ port->mcast_count = 0;
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family == AF_LINK) {
+ if (port->mcast_count == EFX_MAC_MULTICAST_LIST_MAX) {
+ device_printf(sc->dev,
+ "Too many multicast addresses\n");
+ rc = EINVAL;
+ break;
}
+
+ sa = (struct sockaddr_dl *)ifma->ifma_addr;
+ memcpy(mcast_addr, LLADDR(sa), EFX_MAC_ADDR_LEN);
+ mcast_addr += EFX_MAC_ADDR_LEN;
+ ++port->mcast_count;
}
- if_maddr_runlock(ifp);
}
- return (efx_mac_hash_set(enp, bucket));
+ if_maddr_runlock(ifp);
+
+ if (rc == 0) {
+ rc = efx_mac_multicast_list_set(sc->enp, port->mcast_addrs,
+ port->mcast_count);
+ if (rc != 0)
+ device_printf(sc->dev,
+ "Cannot set multicast address list\n");
+ }
+
+ return (rc);
+}
+
+static int
+sfxge_mac_filter_set_locked(struct sfxge_softc *sc)
+{
+ struct ifnet *ifp = sc->ifnet;
+ struct sfxge_port *port = &sc->port;
+ boolean_t all_mulcst;
+ int rc;
+
+ mtx_assert(&port->lock, MA_OWNED);
+
+ all_mulcst = !!(ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI));
+
+ rc = sfxge_mac_multicast_list_set(sc);
+ /* Fallback to all multicast if cannot set multicast list */
+ if (rc != 0)
+ all_mulcst = B_TRUE;
+
+ rc = efx_mac_filter_set(sc->enp, !!(ifp->if_flags & IFF_PROMISC),
+ (port->mcast_count > 0), all_mulcst, B_TRUE);
+
+ return (rc);
}
int
@@ -431,7 +458,9 @@ sfxge_port_stop(struct sfxge_softc *sc)
port->link_mode = EFX_LINK_UNKNOWN;
/* Destroy the common code port object. */
- efx_port_fini(sc->enp);
+ efx_port_fini(enp);
+
+ efx_filter_fini(enp);
SFXGE_PORT_UNLOCK(port);
}
@@ -455,6 +484,10 @@ sfxge_port_start(struct sfxge_softc *sc)
KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
("port not initialized"));
+ /* Initialise the required filtering */
+ if ((rc = efx_filter_init(enp)) != 0)
+ goto fail_filter_init;
+
/* Initialize the port object in the common code. */
if ((rc = efx_port_init(sc->enp)) != 0)
goto fail;
@@ -466,7 +499,7 @@ sfxge_port_start(struct sfxge_softc *sc)
if ((rc = efx_mac_fcntl_set(enp, sfxge_port_wanted_fc(sc), B_TRUE))
!= 0)
- goto fail2;
+ goto fail3;
/* Set the unicast address */
if_addr_rlock(ifp);
@@ -474,24 +507,24 @@ sfxge_port_start(struct sfxge_softc *sc)
mac_addr, sizeof(mac_addr));
if_addr_runlock(ifp);
if ((rc = efx_mac_addr_set(enp, mac_addr)) != 0)
- goto fail;
+ goto fail4;
sfxge_mac_filter_set_locked(sc);
/* Update MAC stats by DMA every second */
if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
- 1000, B_FALSE)) != 0)
- goto fail2;
+ 1000, B_FALSE)) != 0)
+ goto fail6;
if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
- goto fail3;
+ goto fail8;
if ((rc = sfxge_phy_cap_mask(sc, sc->media.ifm_cur->ifm_media,
&phy_cap_mask)) != 0)
- goto fail4;
+ goto fail9;
if ((rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask)) != 0)
- goto fail5;
+ goto fail10;
port->init_state = SFXGE_PORT_STARTED;
@@ -501,15 +534,20 @@ sfxge_port_start(struct sfxge_softc *sc)
return (0);
-fail5:
-fail4:
+fail10:
+fail9:
(void)efx_mac_drain(enp, B_TRUE);
+fail8:
+ (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE);
+fail6:
+fail4:
fail3:
- (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
- 0, B_FALSE);
+
fail2:
- efx_port_fini(sc->enp);
+ efx_port_fini(enp);
fail:
+ efx_filter_fini(enp);
+fail_filter_init:
SFXGE_PORT_UNLOCK(port);
return (rc);
@@ -652,12 +690,14 @@ sfxge_port_init(struct sfxge_softc *sc)
SFXGE_PORT_LOCK_INIT(port, device_get_nameunit(sc->dev));
+ DBGPRINT(sc->dev, "alloc PHY stats");
port->phy_stats.decode_buf = malloc(EFX_PHY_NSTATS * sizeof(uint32_t),
M_SFXGE, M_WAITOK | M_ZERO);
if ((rc = sfxge_dma_alloc(sc, EFX_PHY_STATS_SIZE, phy_stats_buf)) != 0)
goto fail;
sfxge_phy_stat_init(sc);
+ DBGPRINT(sc->dev, "init sysctl");
sysctl_ctx = device_get_sysctl_ctx(sc->dev);
sysctl_tree = device_get_sysctl_tree(sc->dev);
@@ -673,6 +713,7 @@ sfxge_port_init(struct sfxge_softc *sc)
sfxge_port_link_fc_handler, "IU", "link flow control mode");
#endif
+ DBGPRINT(sc->dev, "alloc MAC stats");
port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t),
M_SFXGE, M_WAITOK | M_ZERO);
if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0)
@@ -681,6 +722,7 @@ sfxge_port_init(struct sfxge_softc *sc)
port->init_state = SFXGE_PORT_INITIALIZED;
+ DBGPRINT(sc->dev, "success");
return (0);
fail2:
@@ -690,6 +732,7 @@ fail:
free(port->phy_stats.decode_buf, M_SFXGE);
SFXGE_PORT_LOCK_DESTROY(port);
port->sc = NULL;
+ DBGPRINT(sc->dev, "failed %d", rc);
return (rc);
}
@@ -704,6 +747,11 @@ static const int sfxge_link_mode[EFX_PHY_MEDIA_NTYPES][EFX_LINK_NMODES] = {
/* Don't know the module type, but assume SR for now. */
[EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR,
},
+ [EFX_PHY_MEDIA_QSFP_PLUS] = {
+ /* Don't know the module type, but assume SR for now. */
+ [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR,
+ [EFX_LINK_40000FDX] = IFM_ETHER | IFM_FDX | IFM_40G_CR4,
+ },
[EFX_PHY_MEDIA_SFP_PLUS] = {
/* Don't know the module type, but assume SX/SR for now. */
[EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_SX,
@@ -763,6 +811,8 @@ sfxge_link_mode_to_phy_cap(efx_link_mode_t mode)
return (EFX_PHY_CAP_1000FDX);
case EFX_LINK_10000FDX:
return (EFX_PHY_CAP_10000FDX);
+ case EFX_LINK_40000FDX:
+ return (EFX_PHY_CAP_40000FDX);
default:
EFSYS_ASSERT(B_FALSE);
return (EFX_PHY_CAP_INVALID);
@@ -772,6 +822,8 @@ sfxge_link_mode_to_phy_cap(efx_link_mode_t mode)
static int
sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask)
{
+ /* Get global options (duplex), type and subtype bits */
+ int ifmedia_masked = ifmedia & (IFM_GMASK | IFM_NMASK | IFM_TMASK);
efx_phy_media_type_t medium_type;
boolean_t mode_found = B_FALSE;
uint32_t cap_mask, mode_cap_mask;
@@ -787,7 +839,7 @@ sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask)
efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
- if (ifmedia == sfxge_link_mode[medium_type][mode]) {
+ if (ifmedia_masked == sfxge_link_mode[medium_type][mode]) {
mode_found = B_TRUE;
break;
}
@@ -798,8 +850,8 @@ sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask)
* If media is not in the table, it must be IFM_AUTO.
*/
KASSERT((cap_mask & (1 << EFX_PHY_CAP_AN)) &&
- ifmedia == (IFM_ETHER | IFM_AUTO),
- ("%s: no mode for media %d", __func__, ifmedia));
+ ifmedia_masked == (IFM_ETHER | IFM_AUTO),
+ ("%s: no mode for media %#x", __func__, ifmedia));
*phy_cap_mask = (cap_mask & ~(1 << EFX_PHY_CAP_ASYM));
return (0);
}
@@ -868,9 +920,13 @@ int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
int mode_ifm, best_mode_ifm = 0;
int rc;
- /* We need port state to initialise the ifmedia list. */
- if ((rc = efx_nic_init(sc->enp)) != 0)
- goto out;
+ /*
+ * We need port state to initialise the ifmedia list.
+ * It requires initialized NIC what is already done in
+ * sfxge_create() when resources are estimated.
+ */
+ if ((rc = efx_filter_init(sc->enp)) != 0)
+ goto out1;
if ((rc = efx_port_init(sc->enp)) != 0)
goto out2;
@@ -940,7 +996,7 @@ int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
/* Now discard port state until interface is started. */
efx_port_fini(sc->enp);
out2:
- efx_nic_fini(sc->enp);
-out:
+ efx_filter_fini(sc->enp);
+out1:
return (rc);
}
diff --git a/sys/dev/sfxge/sfxge_rx.c b/sys/dev/sfxge/sfxge_rx.c
index 2535e8777fa0..3782c3496674 100644
--- a/sys/dev/sfxge/sfxge_rx.c
+++ b/sys/dev/sfxge/sfxge_rx.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
#include <sys/cdefs.h>
@@ -35,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
+#include <sys/syslog.h>
#include <sys/limits.h>
#include <sys/syslog.h>
@@ -256,7 +261,7 @@ sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying)
return;
batch = 0;
- mblksize = sc->rx_buffer_size;
+ mblksize = sc->rx_buffer_size - sc->rx_buffer_align;
while (ntodo-- > 0) {
unsigned int id;
struct sfxge_rx_sw_desc *rx_desc;
@@ -271,6 +276,12 @@ sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying)
m = rx_desc->mbuf = sfxge_rx_alloc_mbuf(sc);
if (m == NULL)
break;
+
+ /* m_len specifies length of area to be mapped for DMA */
+ m->m_len = mblksize;
+ m->m_data = (caddr_t)P2ROUNDUP((uintptr_t)m->m_data, CACHE_LINE_SIZE);
+ m->m_data += sc->rx_buffer_align;
+
sfxge_map_mbuf_fast(rxq->mem.esm_tag, rxq->mem.esm_map, m, &seg);
addr[batch++] = seg.ds_addr;
@@ -295,7 +306,15 @@ sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying)
bus_dmamap_sync(rxq->mem.esm_tag, rxq->mem.esm_map,
BUS_DMASYNC_PREWRITE);
- efx_rx_qpush(rxq->common, rxq->added);
+ efx_rx_qpush(rxq->common, rxq->added, &rxq->pushed);
+
+ /* The queue could still be empty if no descriptors were actually
+ * pushed, in which case there will be no event to cause the next
+ * refill, so we must schedule a refill ourselves.
+ */
+ if(rxq->pushed == rxq->completed) {
+ sfxge_rx_schedule_refill(rxq, retrying);
+ }
}
void
@@ -332,8 +351,10 @@ sfxge_rx_deliver(struct sfxge_softc *sc, struct sfxge_rx_sw_desc *rx_desc)
csum_flags |= CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
if (flags & (EFX_PKT_IPV4 | EFX_PKT_IPV6)) {
- m->m_pkthdr.flowid = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ,
- mtod(m, uint8_t *));
+ m->m_pkthdr.flowid =
+ efx_psuedo_hdr_hash_get(sc->enp,
+ EFX_RX_HASHALG_TOEPLITZ,
+ mtod(m, uint8_t *));
/* The hash covers a 4-tuple for TCP only */
M_HASHTYPE_SET(m,
(flags & EFX_PKT_IPV4) ?
@@ -666,8 +687,9 @@ sfxge_lro(struct sfxge_rxq *rxq, struct sfxge_rx_sw_desc *rx_buf)
unsigned bucket;
/* Get the hardware hash */
- conn_hash = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ,
- mtod(m, uint8_t *));
+ conn_hash = efx_psuedo_hdr_hash_get(sc->enp,
+ EFX_RX_HASHALG_TOEPLITZ,
+ mtod(m, uint8_t *));
eh = (struct ether_header *)(m->m_data + sc->rx_prefix_size);
if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
@@ -824,6 +846,17 @@ sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop)
if (rx_desc->flags & (EFX_ADDR_MISMATCH | EFX_DISCARD))
goto discard;
+ /* Read the length from the psuedo header if required */
+ if (rx_desc->flags & EFX_PKT_PREFIX_LEN) {
+ uint16_t tmp_size;
+ int rc;
+ rc = efx_psuedo_hdr_pkt_length_get(sc->enp,
+ mtod(m, uint8_t *),
+ &tmp_size);
+ KASSERT(rc == 0, ("cannot get packet length: %d", rc));
+ rx_desc->size = (int)tmp_size + sc->rx_prefix_size;
+ }
+
prefetch_read_many(mtod(m, caddr_t));
switch (rx_desc->flags & (EFX_PKT_IPV4 | EFX_PKT_IPV6)) {
@@ -908,6 +941,9 @@ sfxge_rx_qstop(struct sfxge_softc *sc, unsigned int index)
struct sfxge_rxq *rxq;
struct sfxge_evq *evq;
unsigned int count;
+ unsigned int retry = 3;
+
+ SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
rxq = sc->rxq[index];
evq = sc->evq[index];
@@ -921,30 +957,43 @@ sfxge_rx_qstop(struct sfxge_softc *sc, unsigned int index)
callout_stop(&rxq->refill_callout);
-again:
- rxq->flush_state = SFXGE_FLUSH_PENDING;
+ while (rxq->flush_state != SFXGE_FLUSH_DONE && retry != 0) {
+ rxq->flush_state = SFXGE_FLUSH_PENDING;
- /* Flush the receive queue */
- efx_rx_qflush(rxq->common);
+ SFXGE_EVQ_UNLOCK(evq);
- SFXGE_EVQ_UNLOCK(evq);
-
- count = 0;
- do {
- /* Spin for 100 ms */
- DELAY(100000);
-
- if (rxq->flush_state != SFXGE_FLUSH_PENDING)
+ /* Flush the receive queue */
+ if (efx_rx_qflush(rxq->common) != 0) {
+ SFXGE_EVQ_LOCK(evq);
+ rxq->flush_state = SFXGE_FLUSH_FAILED;
break;
+ }
- } while (++count < 20);
+ count = 0;
+ do {
+ /* Spin for 100 ms */
+ DELAY(100000);
- SFXGE_EVQ_LOCK(evq);
+ if (rxq->flush_state != SFXGE_FLUSH_PENDING)
+ break;
- if (rxq->flush_state == SFXGE_FLUSH_FAILED)
- goto again;
+ } while (++count < 20);
- rxq->flush_state = SFXGE_FLUSH_DONE;
+ SFXGE_EVQ_LOCK(evq);
+
+ if (rxq->flush_state == SFXGE_FLUSH_PENDING) {
+ /* Flush timeout - neither done nor failed */
+ log(LOG_ERR, "%s: Cannot flush Rx queue %u\n",
+ device_get_nameunit(sc->dev), index);
+ rxq->flush_state = SFXGE_FLUSH_DONE;
+ }
+ retry--;
+ }
+ if (rxq->flush_state == SFXGE_FLUSH_FAILED) {
+ log(LOG_ERR, "%s: Flushing Rx queue %u failed\n",
+ device_get_nameunit(sc->dev), index);
+ rxq->flush_state = SFXGE_FLUSH_DONE;
+ }
rxq->pending = rxq->added;
sfxge_rx_qcomplete(rxq, B_TRUE);
@@ -953,6 +1002,7 @@ again:
("rxq->completed != rxq->pending"));
rxq->added = 0;
+ rxq->pushed = 0;
rxq->pending = 0;
rxq->completed = 0;
rxq->loopback = 0;
@@ -974,6 +1024,8 @@ sfxge_rx_qstart(struct sfxge_softc *sc, unsigned int index)
struct sfxge_evq *evq;
int rc;
+ SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
+
rxq = sc->rxq[index];
esmp = &rxq->mem;
evq = sc->evq[index];
@@ -1000,6 +1052,7 @@ sfxge_rx_qstart(struct sfxge_softc *sc, unsigned int index)
efx_rx_qenable(rxq->common);
rxq->init_state = SFXGE_RXQ_STARTED;
+ rxq->flush_state = SFXGE_FLUSH_REQUIRED;
/* Try to fill the queue from the pool. */
sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(sc->rxq_entries), B_FALSE);
@@ -1019,6 +1072,8 @@ sfxge_rx_stop(struct sfxge_softc *sc)
{
int index;
+ efx_mac_filter_default_rxq_clear(sc->enp);
+
/* Stop the receive queue(s) */
index = sc->rxq_count;
while (--index >= 0)
@@ -1034,6 +1089,8 @@ int
sfxge_rx_start(struct sfxge_softc *sc)
{
struct sfxge_intr *intr;
+ const efx_nic_cfg_t *encp;
+ size_t hdrlen, align, reserved;
int index;
int rc;
@@ -1043,17 +1100,35 @@ sfxge_rx_start(struct sfxge_softc *sc)
if ((rc = efx_rx_init(sc->enp)) != 0)
return (rc);
- /* Calculate the receive packet buffer size. */
- sc->rx_prefix_size = EFX_RX_PREFIX_SIZE;
- sc->rx_buffer_size = (EFX_MAC_PDU(sc->ifnet->if_mtu) +
- sc->rx_prefix_size);
+ encp = efx_nic_cfg_get(sc->enp);
+ sc->rx_buffer_size = EFX_MAC_PDU(sc->ifnet->if_mtu);
+
+ /* Calculate the receive packet buffer size. */
+ sc->rx_prefix_size = encp->enc_rx_prefix_size;
+
+ /* Ensure IP headers are 32bit aligned */
+ hdrlen = sc->rx_prefix_size + sizeof (struct ether_header);
+ sc->rx_buffer_align = P2ROUNDUP(hdrlen, 4) - hdrlen;
+
+ sc->rx_buffer_size += sc->rx_buffer_align;
+
+ /* Align end of packet buffer for RX DMA end padding */
+ align = MAX(1, encp->enc_rx_buf_align_end);
+ EFSYS_ASSERT(ISP2(align));
+ sc->rx_buffer_size = P2ROUNDUP(sc->rx_buffer_size, align);
+
+ /*
+ * Standard mbuf zones only guarantee pointer-size alignment;
+ * we need extra space to align to the cache line
+ */
+ reserved = sc->rx_buffer_size + CACHE_LINE_SIZE;
/* Select zone for packet buffers */
- if (sc->rx_buffer_size <= MCLBYTES)
+ if (reserved <= MCLBYTES)
sc->rx_buffer_zone = zone_clust;
- else if (sc->rx_buffer_size <= MJUMPAGESIZE)
+ else if (reserved <= MJUMPAGESIZE)
sc->rx_buffer_zone = zone_jumbop;
- else if (sc->rx_buffer_size <= MJUM9BYTES)
+ else if (reserved <= MJUM9BYTES)
sc->rx_buffer_zone = zone_jumbo9;
else
sc->rx_buffer_zone = zone_jumbo16;
@@ -1070,8 +1145,8 @@ sfxge_rx_start(struct sfxge_softc *sc)
(1 << EFX_RX_HASH_IPV4) | (1 << EFX_RX_HASH_TCPIPV4) |
(1 << EFX_RX_HASH_IPV6) | (1 << EFX_RX_HASH_TCPIPV6), B_TRUE);
- if ((rc = efx_rx_scale_toeplitz_ipv4_key_set(sc->enp, toep_key,
- sizeof(toep_key))) != 0)
+ if ((rc = efx_rx_scale_key_set(sc->enp, toep_key,
+ sizeof(toep_key))) != 0)
goto fail;
/* Start the receive queue(s). */
@@ -1080,8 +1155,14 @@ sfxge_rx_start(struct sfxge_softc *sc)
goto fail2;
}
+ rc = efx_mac_filter_default_rxq_set(sc->enp, sc->rxq[0]->common,
+ sc->intr.n_alloc > 1);
+ if (rc != 0)
+ goto fail3;
+
return (0);
+fail3:
fail2:
while (--index >= 0)
sfxge_rx_qstop(sc, index);
diff --git a/sys/dev/sfxge/sfxge_rx.h b/sys/dev/sfxge/sfxge_rx.h
index dae7e0893c6d..e870ed5bfdd4 100644
--- a/sys/dev/sfxge/sfxge_rx.h
+++ b/sys/dev/sfxge/sfxge_rx.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -39,22 +43,22 @@
#define SFXGE_LRO 1
#endif
-#define SFXGE_MAGIC_RESERVED 0x8000
+#define SFXGE_MAGIC_RESERVED 0x8000
#define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6
-#define SFXGE_MAGIC_DMAQ_LABEL_MASK \
+#define SFXGE_MAGIC_DMAQ_LABEL_MASK \
((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1)
-#define SFXGE_MAGIC_RX_QFLUSH_DONE \
+#define SFXGE_MAGIC_RX_QFLUSH_DONE \
(SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
-#define SFXGE_MAGIC_RX_QFLUSH_FAILED \
+#define SFXGE_MAGIC_RX_QFLUSH_FAILED \
(SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
-#define SFXGE_MAGIC_RX_QREFILL \
+#define SFXGE_MAGIC_RX_QREFILL \
(SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
-#define SFXGE_MAGIC_TX_QFLUSH_DONE \
+#define SFXGE_MAGIC_TX_QFLUSH_DONE \
(SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
#define SFXGE_RX_SCALE_MAX EFX_MAXRSS
@@ -152,6 +156,7 @@ struct sfxge_lro_state {
enum sfxge_flush_state {
SFXGE_FLUSH_DONE = 0,
+ SFXGE_FLUSH_REQUIRED,
SFXGE_FLUSH_PENDING,
SFXGE_FLUSH_FAILED
};
@@ -175,6 +180,7 @@ struct sfxge_rxq {
struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE);
unsigned int added;
+ unsigned int pushed;
unsigned int pending;
unsigned int completed;
unsigned int loopback;
diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c
index 524b09d840c0..af8efc26be46 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*/
/* Theory of operation:
@@ -67,23 +71,6 @@ __FBSDID("$FreeBSD$");
#include "sfxge.h"
#include "sfxge_tx.h"
-/*
- * Estimate maximum number of Tx descriptors required for TSO packet.
- * With minimum MSS and maximum mbuf length we might need more (even
- * than a ring-ful of descriptors), but this should not happen in
- * practice except due to deliberate attack. In that case we will
- * truncate the output at a packet boundary.
- */
-#define SFXGE_TSO_MAX_DESC \
- (SFXGE_TSO_MAX_SEGS * 2 + SFXGE_TX_MAPPING_MAX_SEG - 1)
-
-/*
- * Set the block level to ensure there is space to generate a
- * large number of descriptors for TSO.
- */
-#define SFXGE_TXQ_BLOCK_LEVEL(_entries) \
- (EFX_TXQ_LIMIT(_entries) - SFXGE_TSO_MAX_DESC)
-
#define SFXGE_PARAM_TX_DPL_GET_MAX SFXGE_PARAM(tx_dpl_get_max)
static int sfxge_tx_dpl_get_max = SFXGE_TX_DPL_GET_PKT_LIMIT_DEFAULT;
@@ -108,6 +95,13 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_dpl_put_max, CTLFLAG_RDTUN,
&sfxge_tx_dpl_put_max, 0,
"Maximum number of any packets in deferred packet put-list");
+#define SFXGE_PARAM_TSO_FW_ASSISTED SFXGE_PARAM(tso_fw_assisted)
+static int sfxge_tso_fw_assisted = 1;
+TUNABLE_INT(SFXGE_PARAM_TSO_FW_ASSISTED, &sfxge_tso_fw_assisted);
+SYSCTL_INT(_hw_sfxge, OID_AUTO, tso_fw_assisted, CTLFLAG_RDTUN,
+ &sfxge_tso_fw_assisted, 0,
+ "Use FW-assisted TSO if supported by NIC firmware");
+
static const struct {
const char *name;
@@ -134,7 +128,38 @@ static void sfxge_tx_qdpl_service(struct sfxge_txq *txq);
static void sfxge_tx_qlist_post(struct sfxge_txq *txq);
static void sfxge_tx_qunblock(struct sfxge_txq *txq);
static int sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
- const bus_dma_segment_t *dma_seg, int n_dma_seg);
+ const bus_dma_segment_t *dma_seg, int n_dma_seg,
+ int vlan_tagged);
+
+static int
+sfxge_tx_maybe_insert_tag(struct sfxge_txq *txq, struct mbuf *mbuf)
+{
+ uint16_t this_tag = ((mbuf->m_flags & M_VLANTAG) ?
+ mbuf->m_pkthdr.ether_vtag :
+ 0);
+
+ if (this_tag == txq->hw_vlan_tci)
+ return (0);
+
+ efx_tx_qdesc_vlantci_create(txq->common,
+ bswap16(this_tag),
+ &txq->pend_desc[0]);
+ txq->n_pend_desc = 1;
+ txq->hw_vlan_tci = this_tag;
+ return (1);
+}
+
+static inline void
+sfxge_next_stmp(struct sfxge_txq *txq, struct sfxge_tx_mapping **pstmp)
+{
+ KASSERT((*pstmp)->flags == 0, ("stmp flags are not 0"));
+ if (__predict_false(*pstmp ==
+ &txq->stmp[txq->ptr_mask]))
+ *pstmp = &txq->stmp[0];
+ else
+ (*pstmp)++;
+}
+
void
sfxge_tx_qcomplete(struct sfxge_txq *txq, struct sfxge_evq *evq)
@@ -252,29 +277,30 @@ static void
sfxge_tx_qlist_post(struct sfxge_txq *txq)
{
unsigned int old_added;
+ unsigned int block_level;
unsigned int level;
int rc;
SFXGE_TXQ_LOCK_ASSERT_OWNED(txq);
KASSERT(txq->n_pend_desc != 0, ("txq->n_pend_desc == 0"));
- KASSERT(txq->n_pend_desc <= SFXGE_TSO_MAX_DESC,
+ KASSERT(txq->n_pend_desc <= txq->max_pkt_desc,
("txq->n_pend_desc too large"));
KASSERT(!txq->blocked, ("txq->blocked"));
old_added = txq->added;
/* Post the fragment list. */
- rc = efx_tx_qpost(txq->common, txq->pend_desc, txq->n_pend_desc,
+ rc = efx_tx_qdesc_post(txq->common, txq->pend_desc, txq->n_pend_desc,
txq->reaped, &txq->added);
- KASSERT(rc == 0, ("efx_tx_qpost() failed"));
+ KASSERT(rc == 0, ("efx_tx_qdesc_post() failed"));
- /* If efx_tx_qpost() had to refragment, our information about
+ /* If efx_tx_qdesc_post() had to refragment, our information about
* buffers to free may be associated with the wrong
* descriptors.
*/
KASSERT(txq->added - old_added == txq->n_pend_desc,
- ("efx_tx_qpost() refragmented descriptors"));
+ ("efx_tx_qdesc_post() refragmented descriptors"));
level = txq->added - txq->reaped;
KASSERT(level <= txq->entries, ("overfilled TX queue"));
@@ -282,14 +308,20 @@ sfxge_tx_qlist_post(struct sfxge_txq *txq)
/* Clear the fragment list. */
txq->n_pend_desc = 0;
+ /*
+ * Set the block level to ensure there is space to generate a
+ * large number of descriptors for TSO.
+ */
+ block_level = EFX_TXQ_LIMIT(txq->entries) - txq->max_pkt_desc;
+
/* Have we reached the block level? */
- if (level < SFXGE_TXQ_BLOCK_LEVEL(txq->entries))
+ if (level < block_level)
return;
/* Reap, and check again */
sfxge_tx_qreap(txq);
level = txq->added - txq->reaped;
- if (level < SFXGE_TXQ_BLOCK_LEVEL(txq->entries))
+ if (level < block_level)
return;
txq->blocked = 1;
@@ -301,7 +333,7 @@ sfxge_tx_qlist_post(struct sfxge_txq *txq)
mb();
sfxge_tx_qreap(txq);
level = txq->added - txq->reaped;
- if (level < SFXGE_TXQ_BLOCK_LEVEL(txq->entries)) {
+ if (level < block_level) {
mb();
txq->blocked = 0;
}
@@ -314,10 +346,12 @@ static int sfxge_tx_queue_mbuf(struct sfxge_txq *txq, struct mbuf *mbuf)
bus_dma_segment_t dma_seg[SFXGE_TX_MAPPING_MAX_SEG];
unsigned int id;
struct sfxge_tx_mapping *stmp;
- efx_buffer_t *desc;
+ efx_desc_t *desc;
int n_dma_seg;
int rc;
int i;
+ int eop;
+ int vlan_tagged;
KASSERT(!txq->blocked, ("txq->blocked"));
@@ -354,35 +388,35 @@ static int sfxge_tx_queue_mbuf(struct sfxge_txq *txq, struct mbuf *mbuf)
used_map = &stmp->map;
+ vlan_tagged = sfxge_tx_maybe_insert_tag(txq, mbuf);
+ if (vlan_tagged) {
+ sfxge_next_stmp(txq, &stmp);
+ }
if (mbuf->m_pkthdr.csum_flags & CSUM_TSO) {
- rc = sfxge_tx_queue_tso(txq, mbuf, dma_seg, n_dma_seg);
+ rc = sfxge_tx_queue_tso(txq, mbuf, dma_seg, n_dma_seg, vlan_tagged);
if (rc < 0)
goto reject_mapped;
- stmp = &txq->stmp[rc];
+ stmp = &txq->stmp[(rc - 1) & txq->ptr_mask];
} else {
/* Add the mapping to the fragment list, and set flags
* for the buffer.
*/
+
i = 0;
for (;;) {
- desc = &txq->pend_desc[i];
- desc->eb_addr = dma_seg[i].ds_addr;
- desc->eb_size = dma_seg[i].ds_len;
- if (i == n_dma_seg - 1) {
- desc->eb_eop = 1;
+ desc = &txq->pend_desc[i + vlan_tagged];
+ eop = (i == n_dma_seg - 1);
+ efx_tx_qdesc_dma_create(txq->common,
+ dma_seg[i].ds_addr,
+ dma_seg[i].ds_len,
+ eop,
+ desc);
+ if (eop)
break;
- }
- desc->eb_eop = 0;
i++;
-
- stmp->flags = 0;
- if (__predict_false(stmp ==
- &txq->stmp[txq->ptr_mask]))
- stmp = &txq->stmp[0];
- else
- stmp++;
+ sfxge_next_stmp(txq, &stmp);
}
- txq->n_pend_desc = n_dma_seg;
+ txq->n_pend_desc = n_dma_seg + vlan_tagged;
}
/*
@@ -469,7 +503,7 @@ sfxge_tx_qdpl_drain(struct sfxge_txq *txq)
/* Push the fragments to the hardware in batches. */
if (txq->added - pushed >= SFXGE_TX_BATCH) {
- efx_tx_qpush(txq->common, txq->added);
+ efx_tx_qpush(txq->common, txq->added, pushed);
pushed = txq->added;
}
}
@@ -489,14 +523,13 @@ sfxge_tx_qdpl_drain(struct sfxge_txq *txq)
}
if (txq->added != pushed)
- efx_tx_qpush(txq->common, txq->added);
+ efx_tx_qpush(txq->common, txq->added, pushed);
KASSERT(txq->blocked || stdp->std_get_count == 0,
("queue unblocked but count is non-zero"));
}
-#define SFXGE_TX_QDPL_PENDING(_txq) \
- ((_txq)->dpl.std_put != 0)
+#define SFXGE_TX_QDPL_PENDING(_txq) ((_txq)->dpl.std_put != 0)
/*
* Service the deferred packet list.
@@ -599,7 +632,7 @@ sfxge_tx_qdpl_put_unlocked(struct sfxge_txq *txq, struct mbuf *mbuf)
* Called from if_transmit - will try to grab the txq lock and enqueue to the
* put list if it succeeds, otherwise try to push onto the defer list if space.
*/
-int
+static int
sfxge_tx_packet_add(struct sfxge_txq *txq, struct mbuf *m)
{
int rc;
@@ -746,6 +779,10 @@ struct sfxge_tso_state {
ssize_t tcph_off; /* Offset of TCP header */
unsigned header_len; /* Number of bytes of header */
unsigned seg_size; /* TCP segment size */
+ int fw_assisted; /* Use FW-assisted TSO */
+ u_short packet_id; /* IPv4 packet ID from the original packet */
+ efx_desc_t header_desc; /* Precomputed header descriptor for
+ * FW-assisted TSO */
};
static const struct ip *tso_iph(const struct sfxge_tso_state *tso)
@@ -816,12 +853,16 @@ static void tso_fini(struct sfxge_txq *txq)
}
}
-static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
+static void tso_start(struct sfxge_txq *txq, struct sfxge_tso_state *tso,
+ const bus_dma_segment_t *hdr_dma_seg,
+ struct mbuf *mbuf)
{
struct ether_header *eh = mtod(mbuf, struct ether_header *);
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(txq->sc->enp);
const struct tcphdr *th;
struct tcphdr th_copy;
+ tso->fw_assisted = txq->sc->tso_fw_assisted;
tso->mbuf = mbuf;
/* Find network protocol and header */
@@ -840,12 +881,19 @@ static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
KASSERT(tso_iph(tso)->ip_p == IPPROTO_TCP,
("TSO required on non-TCP packet"));
tso->tcph_off = tso->nh_off + 4 * tso_iph(tso)->ip_hl;
+ tso->packet_id = tso_iph(tso)->ip_id;
} else {
KASSERT(tso->protocol == htons(ETHERTYPE_IPV6),
("TSO required on non-IP packet"));
KASSERT(tso_ip6h(tso)->ip6_nxt == IPPROTO_TCP,
("TSO required on non-TCP packet"));
tso->tcph_off = tso->nh_off + sizeof(struct ip6_hdr);
+ tso->packet_id = 0;
+ }
+ if (tso->fw_assisted &&
+ __predict_false(tso->tcph_off >
+ encp->enc_tx_tso_tcp_header_offset_limit)) {
+ tso->fw_assisted = 0;
}
KASSERT(mbuf->m_len >= tso->tcph_off,
@@ -875,6 +923,17 @@ static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
th->th_flags & (TH_URG | TH_SYN)));
tso->out_len = mbuf->m_pkthdr.len - tso->header_len;
+
+ if (tso->fw_assisted) {
+ if (hdr_dma_seg->ds_len >= tso->header_len)
+ efx_tx_qdesc_dma_create(txq->common,
+ hdr_dma_seg->ds_addr,
+ tso->header_len,
+ B_FALSE,
+ &tso->header_desc);
+ else
+ tso->fw_assisted = 0;
+ }
}
/*
@@ -887,7 +946,7 @@ static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
static void tso_fill_packet_with_fragment(struct sfxge_txq *txq,
struct sfxge_tso_state *tso)
{
- efx_buffer_t *desc;
+ efx_desc_t *desc;
int n;
if (tso->in_len == 0 || tso->packet_space == 0)
@@ -903,9 +962,11 @@ static void tso_fill_packet_with_fragment(struct sfxge_txq *txq,
tso->in_len -= n;
desc = &txq->pend_desc[txq->n_pend_desc++];
- desc->eb_addr = tso->dma_addr;
- desc->eb_size = n;
- desc->eb_eop = tso->out_len == 0 || tso->packet_space == 0;
+ efx_tx_qdesc_dma_create(txq->common,
+ tso->dma_addr,
+ n,
+ tso->out_len == 0 || tso->packet_space == 0,
+ desc);
tso->dma_addr += n;
}
@@ -928,107 +989,139 @@ static void tso_map_long_header(void *dma_addr_ret,
*/
static int tso_start_new_packet(struct sfxge_txq *txq,
struct sfxge_tso_state *tso,
- unsigned int id)
+ unsigned int *idp)
{
- struct sfxge_tx_mapping *stmp = &txq->stmp[id];
+ unsigned int id = *idp;
struct tcphdr *tsoh_th;
unsigned ip_length;
caddr_t header;
uint64_t dma_addr;
bus_dmamap_t map;
- efx_buffer_t *desc;
+ efx_desc_t *desc;
int rc;
- /* Allocate a DMA-mapped header buffer. */
- if (__predict_true(tso->header_len <= TSOH_STD_SIZE)) {
- unsigned int page_index = (id / 2) / TSOH_PER_PAGE;
- unsigned int buf_index = (id / 2) % TSOH_PER_PAGE;
+ if (tso->fw_assisted) {
+ uint8_t tcp_flags = tso_tcph(tso)->th_flags;
+
+ if (tso->out_len > tso->seg_size)
+ tcp_flags &= ~(TH_FIN | TH_PUSH);
+
+ /* TSO option descriptor */
+ desc = &txq->pend_desc[txq->n_pend_desc++];
+ efx_tx_qdesc_tso_create(txq->common,
+ tso->packet_id,
+ tso->seqnum,
+ tcp_flags,
+ desc++);
+ KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
+ id = (id + 1) & txq->ptr_mask;
- header = (txq->tsoh_buffer[page_index].esm_base +
- buf_index * TSOH_STD_SIZE);
- dma_addr = (txq->tsoh_buffer[page_index].esm_addr +
- buf_index * TSOH_STD_SIZE);
- map = txq->tsoh_buffer[page_index].esm_map;
+ /* Header DMA descriptor */
+ *desc = tso->header_desc;
+ txq->n_pend_desc++;
+ KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
+ id = (id + 1) & txq->ptr_mask;
- stmp->flags = 0;
+ tso->seqnum += tso->seg_size;
} else {
- /* We cannot use bus_dmamem_alloc() as that may sleep */
- header = malloc(tso->header_len, M_SFXGE, M_NOWAIT);
- if (__predict_false(!header))
- return (ENOMEM);
- rc = bus_dmamap_load(txq->packet_dma_tag, stmp->map,
- header, tso->header_len,
- tso_map_long_header, &dma_addr,
- BUS_DMA_NOWAIT);
- if (__predict_false(dma_addr == 0)) {
- if (rc == 0) {
- /* Succeeded but got >1 segment */
- bus_dmamap_unload(txq->packet_dma_tag,
- stmp->map);
- rc = EINVAL;
+ /* Allocate a DMA-mapped header buffer. */
+ if (__predict_true(tso->header_len <= TSOH_STD_SIZE)) {
+ unsigned int page_index = (id / 2) / TSOH_PER_PAGE;
+ unsigned int buf_index = (id / 2) % TSOH_PER_PAGE;
+
+ header = (txq->tsoh_buffer[page_index].esm_base +
+ buf_index * TSOH_STD_SIZE);
+ dma_addr = (txq->tsoh_buffer[page_index].esm_addr +
+ buf_index * TSOH_STD_SIZE);
+ map = txq->tsoh_buffer[page_index].esm_map;
+
+ KASSERT(txq->stmp[id].flags == 0,
+ ("stmp flags are not 0"));
+ } else {
+ struct sfxge_tx_mapping *stmp = &txq->stmp[id];
+
+ /* We cannot use bus_dmamem_alloc() as that may sleep */
+ header = malloc(tso->header_len, M_SFXGE, M_NOWAIT);
+ if (__predict_false(!header))
+ return (ENOMEM);
+ rc = bus_dmamap_load(txq->packet_dma_tag, stmp->map,
+ header, tso->header_len,
+ tso_map_long_header, &dma_addr,
+ BUS_DMA_NOWAIT);
+ if (__predict_false(dma_addr == 0)) {
+ if (rc == 0) {
+ /* Succeeded but got >1 segment */
+ bus_dmamap_unload(txq->packet_dma_tag,
+ stmp->map);
+ rc = EINVAL;
+ }
+ free(header, M_SFXGE);
+ return (rc);
}
- free(header, M_SFXGE);
- return (rc);
- }
- map = stmp->map;
+ map = stmp->map;
- txq->tso_long_headers++;
- stmp->u.heap_buf = header;
- stmp->flags = TX_BUF_UNMAP;
- }
+ txq->tso_long_headers++;
+ stmp->u.heap_buf = header;
+ stmp->flags = TX_BUF_UNMAP;
+ }
- tsoh_th = (struct tcphdr *)(header + tso->tcph_off);
+ tsoh_th = (struct tcphdr *)(header + tso->tcph_off);
- /* Copy and update the headers. */
- m_copydata(tso->mbuf, 0, tso->header_len, header);
+ /* Copy and update the headers. */
+ m_copydata(tso->mbuf, 0, tso->header_len, header);
- tsoh_th->th_seq = htonl(tso->seqnum);
- tso->seqnum += tso->seg_size;
- if (tso->out_len > tso->seg_size) {
- /* This packet will not finish the TSO burst. */
- ip_length = tso->header_len - tso->nh_off + tso->seg_size;
- tsoh_th->th_flags &= ~(TH_FIN | TH_PUSH);
- } else {
- /* This packet will be the last in the TSO burst. */
- ip_length = tso->header_len - tso->nh_off + tso->out_len;
- }
+ tsoh_th->th_seq = htonl(tso->seqnum);
+ tso->seqnum += tso->seg_size;
+ if (tso->out_len > tso->seg_size) {
+ /* This packet will not finish the TSO burst. */
+ ip_length = tso->header_len - tso->nh_off + tso->seg_size;
+ tsoh_th->th_flags &= ~(TH_FIN | TH_PUSH);
+ } else {
+ /* This packet will be the last in the TSO burst. */
+ ip_length = tso->header_len - tso->nh_off + tso->out_len;
+ }
- if (tso->protocol == htons(ETHERTYPE_IP)) {
- struct ip *tsoh_iph = (struct ip *)(header + tso->nh_off);
- tsoh_iph->ip_len = htons(ip_length);
- /* XXX We should increment ip_id, but FreeBSD doesn't
- * currently allocate extra IDs for multiple segments.
- */
- } else {
- struct ip6_hdr *tsoh_iph =
- (struct ip6_hdr *)(header + tso->nh_off);
- tsoh_iph->ip6_plen = htons(ip_length - sizeof(*tsoh_iph));
- }
+ if (tso->protocol == htons(ETHERTYPE_IP)) {
+ struct ip *tsoh_iph = (struct ip *)(header + tso->nh_off);
+ tsoh_iph->ip_len = htons(ip_length);
+ /* XXX We should increment ip_id, but FreeBSD doesn't
+ * currently allocate extra IDs for multiple segments.
+ */
+ } else {
+ struct ip6_hdr *tsoh_iph =
+ (struct ip6_hdr *)(header + tso->nh_off);
+ tsoh_iph->ip6_plen = htons(ip_length - sizeof(*tsoh_iph));
+ }
- /* Make the header visible to the hardware. */
- bus_dmamap_sync(txq->packet_dma_tag, map, BUS_DMASYNC_PREWRITE);
+ /* Make the header visible to the hardware. */
+ bus_dmamap_sync(txq->packet_dma_tag, map, BUS_DMASYNC_PREWRITE);
+ /* Form a descriptor for this header. */
+ desc = &txq->pend_desc[txq->n_pend_desc++];
+ efx_tx_qdesc_dma_create(txq->common,
+ dma_addr,
+ tso->header_len,
+ 0,
+ desc);
+ id = (id + 1) & txq->ptr_mask;
+ }
tso->packet_space = tso->seg_size;
txq->tso_packets++;
-
- /* Form a descriptor for this header. */
- desc = &txq->pend_desc[txq->n_pend_desc++];
- desc->eb_addr = dma_addr;
- desc->eb_size = tso->header_len;
- desc->eb_eop = 0;
+ *idp = id;
return (0);
}
static int
sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
- const bus_dma_segment_t *dma_seg, int n_dma_seg)
+ const bus_dma_segment_t *dma_seg, int n_dma_seg,
+ int vlan_tagged)
{
struct sfxge_tso_state tso;
- unsigned int id, next_id;
+ unsigned int id;
unsigned skipped = 0;
- tso_start(&tso, mbuf);
+ tso_start(txq, &tso, dma_seg, mbuf);
while (dma_seg->ds_len + skipped <= tso.header_len) {
skipped += dma_seg->ds_len;
@@ -1039,13 +1132,15 @@ sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
tso.in_len = dma_seg->ds_len - (tso.header_len - skipped);
tso.dma_addr = dma_seg->ds_addr + (tso.header_len - skipped);
- id = txq->added & txq->ptr_mask;
- if (__predict_false(tso_start_new_packet(txq, &tso, id)))
+ id = (txq->added + vlan_tagged) & txq->ptr_mask;
+ if (__predict_false(tso_start_new_packet(txq, &tso, &id)))
return (-1);
while (1) {
- id = (id + 1) & txq->ptr_mask;
tso_fill_packet_with_fragment(txq, &tso);
+ /* Exactly one DMA descriptor is added */
+ KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
+ id = (id + 1) & txq->ptr_mask;
/* Move onto the next fragment? */
if (tso.in_len == 0) {
@@ -1064,18 +1159,17 @@ sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
* the remainder of the input mbuf but do not
* roll back the work we have done.
*/
- if (txq->n_pend_desc + 1 /* header */ + n_dma_seg >
- SFXGE_TSO_MAX_DESC) {
+ if (txq->n_pend_desc + tso.fw_assisted +
+ 1 /* header */ + n_dma_seg >
+ txq->max_pkt_desc) {
txq->tso_pdrop_too_many++;
break;
}
- next_id = (id + 1) & txq->ptr_mask;
if (__predict_false(tso_start_new_packet(txq, &tso,
- next_id))) {
+ &id))) {
txq->tso_pdrop_no_rsrc++;
break;
}
- id = next_id;
}
}
@@ -1128,38 +1222,52 @@ sfxge_tx_qstop(struct sfxge_softc *sc, unsigned int index)
struct sfxge_evq *evq;
unsigned int count;
+ SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
+
txq = sc->txq[index];
evq = sc->evq[txq->evq_index];
+ SFXGE_EVQ_LOCK(evq);
SFXGE_TXQ_LOCK(txq);
KASSERT(txq->init_state == SFXGE_TXQ_STARTED,
("txq->init_state != SFXGE_TXQ_STARTED"));
txq->init_state = SFXGE_TXQ_INITIALIZED;
- txq->flush_state = SFXGE_FLUSH_PENDING;
-
- /* Flush the transmit queue. */
- efx_tx_qflush(txq->common);
-
- SFXGE_TXQ_UNLOCK(txq);
- count = 0;
- do {
- /* Spin for 100ms. */
- DELAY(100000);
+ if (txq->flush_state != SFXGE_FLUSH_DONE) {
+ txq->flush_state = SFXGE_FLUSH_PENDING;
- if (txq->flush_state != SFXGE_FLUSH_PENDING)
- break;
- } while (++count < 20);
+ SFXGE_EVQ_UNLOCK(evq);
+ SFXGE_TXQ_UNLOCK(txq);
- SFXGE_EVQ_LOCK(evq);
- SFXGE_TXQ_LOCK(txq);
+ /* Flush the transmit queue. */
+ if (efx_tx_qflush(txq->common) != 0) {
+ log(LOG_ERR, "%s: Flushing Tx queue %u failed\n",
+ device_get_nameunit(sc->dev), index);
+ txq->flush_state = SFXGE_FLUSH_DONE;
+ } else {
+ count = 0;
+ do {
+ /* Spin for 100ms. */
+ DELAY(100000);
+ if (txq->flush_state != SFXGE_FLUSH_PENDING)
+ break;
+ } while (++count < 20);
+ }
+ SFXGE_EVQ_LOCK(evq);
+ SFXGE_TXQ_LOCK(txq);
- KASSERT(txq->flush_state != SFXGE_FLUSH_FAILED,
- ("txq->flush_state == SFXGE_FLUSH_FAILED"));
+ KASSERT(txq->flush_state != SFXGE_FLUSH_FAILED,
+ ("txq->flush_state == SFXGE_FLUSH_FAILED"));
- txq->flush_state = SFXGE_FLUSH_DONE;
+ if (txq->flush_state != SFXGE_FLUSH_DONE) {
+ /* Flush timeout */
+ log(LOG_ERR, "%s: Cannot flush Tx queue %u\n",
+ device_get_nameunit(sc->dev), index);
+ txq->flush_state = SFXGE_FLUSH_DONE;
+ }
+ }
txq->blocked = 0;
txq->pending = txq->added;
@@ -1195,8 +1303,11 @@ sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
efsys_mem_t *esmp;
uint16_t flags;
struct sfxge_evq *evq;
+ unsigned int desc_index;
int rc;
+ SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
+
txq = sc->txq[index];
esmp = &txq->mem;
evq = sc->evq[txq->evq_index];
@@ -1231,15 +1342,19 @@ sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
/* Create the common code transmit queue. */
if ((rc = efx_tx_qcreate(sc->enp, index, txq->type, esmp,
sc->txq_entries, txq->buf_base_id, flags, evq->common,
- &txq->common)) != 0)
+ &txq->common, &desc_index)) != 0)
goto fail;
+ /* Initialise queue descriptor indexes */
+ txq->added = txq->pending = txq->completed = txq->reaped = desc_index;
+
SFXGE_TXQ_LOCK(txq);
/* Enable the transmit queue. */
efx_tx_qenable(txq->common);
txq->init_state = SFXGE_TXQ_STARTED;
+ txq->flush_state = SFXGE_FLUSH_REQUIRED;
SFXGE_TXQ_UNLOCK(txq);
@@ -1348,9 +1463,41 @@ sfxge_tx_qfini(struct sfxge_softc *sc, unsigned int index)
free(txq, M_SFXGE);
}
+/*
+ * Estimate maximum number of Tx descriptors required for TSO packet.
+ * With minimum MSS and maximum mbuf length we might need more (even
+ * than a ring-ful of descriptors), but this should not happen in
+ * practice except due to deliberate attack. In that case we will
+ * truncate the output at a packet boundary.
+ */
+static unsigned int
+sfxge_tx_max_pkt_desc(const struct sfxge_softc *sc, enum sfxge_txq_type type)
+{
+ /* One descriptor for every input fragment */
+ unsigned int max_descs = SFXGE_TX_MAPPING_MAX_SEG;
+
+ /* VLAN tagging Tx option descriptor may be required */
+ if (efx_nic_cfg_get(sc->enp)->enc_hw_tx_insert_vlan_enabled)
+ max_descs++;
+
+ if (type == SFXGE_TXQ_IP_TCP_UDP_CKSUM) {
+ /*
+ * Plus header and payload descriptor for each output segment.
+ * Minus one since header fragment is already counted.
+ */
+ max_descs += SFXGE_TSO_MAX_SEGS * 2 - 1;
+
+ /* FW assisted TSO requires one more descriptor per segment */
+ if (sc->tso_fw_assisted)
+ max_descs += SFXGE_TSO_MAX_SEGS;
+ }
+
+ return (max_descs);
+}
+
static int
sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
- enum sfxge_txq_type type, unsigned int evq_index)
+ enum sfxge_txq_type type, unsigned int evq_index)
{
char name[16];
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
@@ -1392,7 +1539,7 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
}
/* Allocate pending descriptor array for batching writes. */
- txq->pend_desc = malloc(sizeof(efx_buffer_t) * sc->txq_entries,
+ txq->pend_desc = malloc(sizeof(efx_desc_t) * sc->txq_entries,
M_SFXGE, M_ZERO | M_WAITOK);
/* Allocate and initialise mbuf DMA mapping array. */
@@ -1475,6 +1622,9 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
txq->evq_index = evq_index;
txq->txq_index = txq_index;
txq->init_state = SFXGE_TXQ_INITIALIZED;
+ txq->hw_vlan_tci = 0;
+
+ txq->max_pkt_desc = sfxge_tx_max_pkt_desc(sc, type);
return (0);
@@ -1572,6 +1722,7 @@ sfxge_tx_fini(struct sfxge_softc *sc)
int
sfxge_tx_init(struct sfxge_softc *sc)
{
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
struct sfxge_intr *intr;
int index;
int rc;
@@ -1583,6 +1734,12 @@ sfxge_tx_init(struct sfxge_softc *sc)
sc->txq_count = SFXGE_TXQ_NTYPES - 1 + sc->intr.n_alloc;
+ sc->tso_fw_assisted = sfxge_tso_fw_assisted;
+ if (sc->tso_fw_assisted)
+ sc->tso_fw_assisted =
+ (encp->enc_features & EFX_FEATURE_FW_ASSISTED_TSO) &&
+ (encp->enc_fw_assisted_tso_enabled);
+
sc->txqs_node = SYSCTL_ADD_NODE(
device_get_sysctl_ctx(sc->dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
diff --git a/sys/dev/sfxge/sfxge_tx.h b/sys/dev/sfxge/sfxge_tx.h
index 724ee2245230..3a1dd5b0114c 100644
--- a/sys/dev/sfxge/sfxge_tx.h
+++ b/sys/dev/sfxge/sfxge_tx.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -164,10 +168,11 @@ struct sfxge_txq {
unsigned int buf_base_id;
unsigned int entries;
unsigned int ptr_mask;
+ unsigned int max_pkt_desc;
struct sfxge_tx_mapping *stmp; /* Packets in flight. */
bus_dma_tag_t packet_dma_tag;
- efx_buffer_t *pend_desc;
+ efx_desc_t *pend_desc;
efx_txq_t *common;
efsys_mem_t *tsoh_buffer;
@@ -187,6 +192,11 @@ struct sfxge_txq {
unsigned int n_pend_desc;
unsigned int added;
unsigned int reaped;
+
+ /* The last VLAN TCI seen on the queue if FW-assisted tagging is
+ used */
+ uint16_t hw_vlan_tci;
+
/* Statistics */
unsigned long tso_bursts;
unsigned long tso_packets;
@@ -210,7 +220,6 @@ struct sfxge_txq {
struct sfxge_evq;
-extern int sfxge_tx_packet_add(struct sfxge_txq *, struct mbuf *);
extern uint64_t sfxge_tx_get_drops(struct sfxge_softc *sc);
extern int sfxge_tx_init(struct sfxge_softc *sc);
diff --git a/sys/dev/sfxge/sfxge_version.h b/sys/dev/sfxge/sfxge_version.h
index d2634518cd57..f5f4882b47d8 100644
--- a/sys/dev/sfxge/sfxge_version.h
+++ b/sys/dev/sfxge/sfxge_version.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2015 Solarflare Communications, Inc.
+ * Copyright (c) 2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by OKTET Labs under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * 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.
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
*
* $FreeBSD$
*/
@@ -32,6 +36,6 @@
#ifndef _SFXGE_VERSION_H
#define _SFXGE_VERSION_H
-#define SFXGE_VERSION_STRING "v3.3.4.6365"
+#define SFXGE_VERSION_STRING "v4.5.2.1000"
#endif /* _SFXGE_DRIVER_VERSION_H */
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 9ff295a972d0..b2810a097273 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -416,10 +416,10 @@ ns8250_bus_attach(struct uart_softc *sc)
* has broken txfifo.
*/
node = ofw_bus_get_node(sc->sc_dev);
- if ((OF_getprop(node, "busy-detect", &cell, sizeof(cell))) > 0)
- ns8250->busy_detect = 1;
- if ((OF_getprop(node, "broken-txfifo", &cell, sizeof(cell))) > 0)
- broken_txfifo = 1;
+ if ((OF_getencprop(node, "busy-detect", &cell, sizeof(cell))) > 0)
+ ns8250->busy_detect = cell ? 1 : 0;
+ if ((OF_getencprop(node, "broken-txfifo", &cell, sizeof(cell))) > 0)
+ broken_txfifo = cell ? 1 : 0;
#endif
bas = &sc->sc_bas;
diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c
index 50ead5c290a7..868c7c7e3461 100644
--- a/sys/dev/usb/controller/dwc_otg.c
+++ b/sys/dev/usb/controller/dwc_otg.c
@@ -180,6 +180,22 @@ dwc_otg_get_hw_ep_profile(struct usb_device *udev,
*ppf = NULL;
}
+static void
+dwc_otg_tx_fifo_reset(struct dwc_otg_softc *sc, uint32_t value)
+{
+ uint32_t temp;
+
+ /* reset FIFO */
+ DWC_OTG_WRITE_4(sc, DOTG_GRSTCTL, value);
+
+ /* wait for reset to complete */
+ for (temp = 0; temp != 16; temp++) {
+ value = DWC_OTG_READ_4(sc, DOTG_GRSTCTL);
+ if (!(value & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH)))
+ break;
+ }
+}
+
static int
dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode)
{
@@ -331,12 +347,11 @@ dwc_otg_init_fifo(struct dwc_otg_softc *sc, uint8_t mode)
}
/* reset RX FIFO */
- DWC_OTG_WRITE_4(sc, DOTG_GRSTCTL,
- GRSTCTL_RXFFLSH);
+ dwc_otg_tx_fifo_reset(sc, GRSTCTL_RXFFLSH);
if (mode != DWC_MODE_OTG) {
/* reset all TX FIFOs */
- DWC_OTG_WRITE_4(sc, DOTG_GRSTCTL,
+ dwc_otg_tx_fifo_reset(sc,
GRSTCTL_TXFIFO(0x10) |
GRSTCTL_TXFFLSH);
} else {
@@ -947,15 +962,21 @@ dwc_otg_setup_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td)
if (GRXSTSRD_CHNUM_GET(sc->sc_last_rx_status) != 0)
goto not_complete;
- if ((sc->sc_last_rx_status & GRXSTSRD_DPID_MASK) !=
- GRXSTSRD_DPID_DATA0) {
+ if ((sc->sc_last_rx_status & GRXSTSRD_PKTSTS_MASK) !=
+ GRXSTSRD_STP_DATA) {
+ if ((sc->sc_last_rx_status & GRXSTSRD_PKTSTS_MASK) !=
+ GRXSTSRD_STP_COMPLETE || td->remainder != 0) {
+ /* release FIFO */
+ dwc_otg_common_rx_ack(sc);
+ goto not_complete;
+ }
/* release FIFO */
dwc_otg_common_rx_ack(sc);
- goto not_complete;
+ return (0); /* complete */
}
- if ((sc->sc_last_rx_status & GRXSTSRD_PKTSTS_MASK) !=
- GRXSTSRD_STP_DATA) {
+ if ((sc->sc_last_rx_status & GRXSTSRD_DPID_MASK) !=
+ GRXSTSRD_DPID_DATA0) {
/* release FIFO */
dwc_otg_common_rx_ack(sc);
goto not_complete;
@@ -969,14 +990,6 @@ dwc_otg_setup_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td)
/* get the packet byte count */
count = GRXSTSRD_BCNT_GET(sc->sc_last_rx_status);
- /* verify data length */
- if (count != td->remainder) {
- DPRINTFN(0, "Invalid SETUP packet "
- "length, %d bytes\n", count);
- /* release FIFO */
- dwc_otg_common_rx_ack(sc);
- goto not_complete;
- }
if (count != sizeof(req)) {
DPRINTFN(0, "Unsupported SETUP packet "
"length, %d bytes\n", count);
@@ -1002,43 +1015,27 @@ dwc_otg_setup_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td)
}
/* don't send any data by default */
- DWC_OTG_WRITE_4(sc, DOTG_DIEPTSIZ(0),
- DXEPTSIZ_SET_NPKT(0) |
- DXEPTSIZ_SET_NBYTES(0));
-
- temp = sc->sc_in_ctl[0];
-
- /* enable IN endpoint */
- DWC_OTG_WRITE_4(sc, DOTG_DIEPCTL(0),
- temp | DIEPCTL_EPENA);
- DWC_OTG_WRITE_4(sc, DOTG_DIEPCTL(0),
- temp | DIEPCTL_SNAK);
+ DWC_OTG_WRITE_4(sc, DOTG_DIEPTSIZ(0), DIEPCTL_EPDIS);
+ DWC_OTG_WRITE_4(sc, DOTG_DOEPTSIZ(0), DOEPCTL_EPDIS);
/* reset IN endpoint buffer */
- DWC_OTG_WRITE_4(sc, DOTG_GRSTCTL,
+ dwc_otg_tx_fifo_reset(sc,
GRSTCTL_TXFIFO(0) |
GRSTCTL_TXFFLSH);
/* acknowledge RX status */
dwc_otg_common_rx_ack(sc);
- return (0); /* complete */
+ td->did_stall = 1;
not_complete:
/* abort any ongoing transfer, before enabling again */
-
- temp = sc->sc_out_ctl[0];
-
- temp |= DOEPCTL_EPENA |
- DOEPCTL_SNAK;
-
- /* enable OUT endpoint */
- DWC_OTG_WRITE_4(sc, DOTG_DOEPCTL(0), temp);
-
if (!td->did_stall) {
td->did_stall = 1;
DPRINTFN(5, "stalling IN and OUT direction\n");
+ temp = sc->sc_out_ctl[0];
+
/* set stall after enabling endpoint */
DWC_OTG_WRITE_4(sc, DOTG_DOEPCTL(0),
temp | DOEPCTL_STALL);
@@ -1049,13 +1046,6 @@ not_complete:
DWC_OTG_WRITE_4(sc, DOTG_DIEPCTL(0),
temp | DIEPCTL_STALL);
}
-
- /* setup number of buffers to receive */
- DWC_OTG_WRITE_4(sc, DOTG_DOEPTSIZ(0),
- DXEPTSIZ_SET_MULTI(3) |
- DXEPTSIZ_SET_NPKT(1) |
- DXEPTSIZ_SET_NBYTES(sizeof(req)));
-
return (1); /* not complete */
}
@@ -1499,7 +1489,9 @@ dwc_otg_data_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td)
/* check for SETUP packet */
if ((sc->sc_last_rx_status & GRXSTSRD_PKTSTS_MASK) ==
- GRXSTSRD_STP_DATA) {
+ GRXSTSRD_STP_DATA ||
+ (sc->sc_last_rx_status & GRXSTSRD_PKTSTS_MASK) ==
+ GRXSTSRD_STP_COMPLETE) {
if (td->remainder == 0) {
/*
* We are actually complete and have
@@ -1584,15 +1576,10 @@ dwc_otg_data_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td)
not_complete:
- temp = sc->sc_out_ctl[td->ep_no];
-
- temp |= DOEPCTL_EPENA | DOEPCTL_CNAK;
-
- DWC_OTG_WRITE_4(sc, DOTG_DOEPCTL(td->ep_no), temp);
-
/* enable SETUP and transfer complete interrupt */
if (td->ep_no == 0) {
DWC_OTG_WRITE_4(sc, DOTG_DOEPTSIZ(0),
+ DXEPTSIZ_SET_MULTI(3) |
DXEPTSIZ_SET_NPKT(1) |
DXEPTSIZ_SET_NBYTES(td->max_packet_size));
} else {
@@ -1601,8 +1588,12 @@ not_complete:
DXEPTSIZ_SET_MULTI(1) |
DXEPTSIZ_SET_NPKT(4) |
DXEPTSIZ_SET_NBYTES(4 *
- ((td->max_packet_size + 3) & ~3)));
+ ((td->max_packet_size + 3) & ~3)));
}
+ temp = sc->sc_out_ctl[td->ep_no];
+ DWC_OTG_WRITE_4(sc, DOTG_DOEPCTL(td->ep_no), temp |
+ DOEPCTL_EPENA | DOEPCTL_CNAK);
+
return (1); /* not complete */
}
@@ -2004,7 +1995,9 @@ repeat:
(GRXSTSRD_CHNUM_GET(temp) == 0)) {
if ((temp & GRXSTSRD_PKTSTS_MASK) !=
- GRXSTSRD_STP_DATA) {
+ GRXSTSRD_STP_DATA &&
+ (temp & GRXSTSRD_PKTSTS_MASK) !=
+ GRXSTSRD_STP_COMPLETE) {
/* dump data - wrong direction */
dwc_otg_common_rx_ack(sc);
@@ -2209,7 +2202,9 @@ not_complete:
(GRXSTSRD_CHNUM_GET(temp) == 0)) {
if ((temp & GRXSTSRD_PKTSTS_MASK) ==
- GRXSTSRD_STP_DATA) {
+ GRXSTSRD_STP_DATA ||
+ (temp & GRXSTSRD_PKTSTS_MASK) ==
+ GRXSTSRD_STP_COMPLETE) {
DPRINTFN(5, "faking complete\n");
/*
* Race condition: We are complete!
@@ -2634,6 +2629,7 @@ repeat:
/* non-data messages we simply skip */
if (temp != GRXSTSRD_STP_DATA &&
+ temp != GRXSTSRD_STP_COMPLETE &&
temp != GRXSTSRD_OUT_DATA) {
dwc_otg_common_rx_ack(sc);
goto repeat;
@@ -3669,7 +3665,7 @@ dwc_otg_clear_stall_sub_locked(struct dwc_otg_softc *sc, uint32_t mps,
/* we only reset the transmit FIFO */
if (ep_dir) {
- DWC_OTG_WRITE_4(sc, DOTG_GRSTCTL,
+ dwc_otg_tx_fifo_reset(sc,
GRSTCTL_TXFIFO(ep_no) |
GRSTCTL_TXFFLSH);
diff --git a/sys/dev/usb/misc/ugold.c b/sys/dev/usb/misc/ugold.c
new file mode 100644
index 000000000000..d6f8f777cac0
--- /dev/null
+++ b/sys/dev/usb/misc/ugold.c
@@ -0,0 +1,405 @@
+/* $OpenBSD: ugold.c,v 1.7 2014/12/11 18:39:27 mpi Exp $ */
+
+/*
+ * Copyright (c) 2013 Takayoshi SASANO <sasano@openbsd.org>
+ * Copyright (c) 2013 Martin Pieuchot <mpi@openbsd.org>
+ *
+ * Permission to use, copy, modify, and 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 DISCAIMS 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.
+ */
+
+/* Driver for Microdia's HID based TEMPer Temperature sensor */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+#include <sys/conf.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbhid.h>
+#include <dev/usb/usb_process.h>
+#include <dev/usb/usbdi_util.h>
+#include "usbdevs.h"
+
+#define USB_DEBUG_VAR usb_debug
+#include <dev/usb/usb_debug.h>
+
+#define UGOLD_INNER 0
+#define UGOLD_OUTER 1
+#define UGOLD_MAX_SENSORS 2
+
+#define UGOLD_CMD_DATA 0x80
+#define UGOLD_CMD_INIT 0x82
+
+enum {
+ UGOLD_INTR_DT,
+ UGOLD_N_TRANSFER,
+};
+
+/*
+ * This driver only uses two of the three known commands for the
+ * TEMPerV1.2 device.
+ *
+ * The first byte of the answer corresponds to the command and the
+ * second one seems to be the size (in bytes) of the answer.
+ *
+ * The device always sends 8 bytes and if the length of the answer
+ * is less than that, it just leaves the last bytes untouched. That
+ * is why most of the time the last n bytes of the answers are the
+ * same.
+ *
+ * The third command below seems to generate two answers with a
+ * string corresponding to the device, for example:
+ * 'TEMPer1F' and '1.1Per1F' (here Per1F is repeated).
+ */
+static uint8_t cmd_data[8] = {0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00};
+static uint8_t cmd_init[8] = {0x01, 0x82, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00};
+
+#if 0
+static uint8_t cmd_type[8] = {0x01, 0x86, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00};
+
+#endif
+
+struct ugold_softc;
+struct ugold_readout_msg {
+ struct usb_proc_msg hdr;
+ struct ugold_softc *sc;
+};
+
+struct ugold_softc {
+ struct usb_device *sc_udev;
+ struct usb_xfer *sc_xfer[UGOLD_N_TRANSFER];
+
+ struct callout sc_callout;
+ struct mtx sc_mtx;
+ struct ugold_readout_msg sc_readout_msg[2];
+
+ int sc_num_sensors;
+ int sc_sensor[UGOLD_MAX_SENSORS];
+ int sc_calib[UGOLD_MAX_SENSORS];
+ int sc_valid[UGOLD_MAX_SENSORS];
+ uint8_t sc_report_id;
+ uint8_t sc_iface_index[2];
+};
+
+/* prototypes */
+
+static device_probe_t ugold_probe;
+static device_attach_t ugold_attach;
+static device_detach_t ugold_detach;
+
+static usb_proc_callback_t ugold_readout_msg;
+
+static usb_callback_t ugold_intr_callback;
+
+static devclass_t ugold_devclass;
+
+static device_method_t ugold_methods[] = {
+ DEVMETHOD(device_probe, ugold_probe),
+ DEVMETHOD(device_attach, ugold_attach),
+ DEVMETHOD(device_detach, ugold_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t ugold_driver = {
+ .name = "ugold",
+ .methods = ugold_methods,
+ .size = sizeof(struct ugold_softc),
+};
+
+DRIVER_MODULE(ugold, uhub, ugold_driver, ugold_devclass, NULL, NULL);
+MODULE_DEPEND(ugold, usb, 1, 1, 1);
+MODULE_VERSION(ugold, 1);
+
+static const struct usb_config ugold_config[UGOLD_N_TRANSFER] = {
+
+ [UGOLD_INTR_DT] = {
+ .type = UE_INTERRUPT,
+ .endpoint = UE_ADDR_ANY,
+ .direction = UE_DIR_IN,
+ .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
+ .bufsize = 0, /* use wMaxPacketSize */
+ .callback = &ugold_intr_callback,
+ .if_index = 1,
+ },
+};
+
+static const STRUCT_USB_HOST_ID ugold_devs[] = {
+ {USB_VPI(USB_VENDOR_CHICONY2, USB_PRODUCT_CHICONY2_TEMPER, 0)},
+};
+
+static void
+ugold_timeout(void *arg)
+{
+ struct ugold_softc *sc = arg;
+
+ usb_proc_explore_lock(sc->sc_udev);
+ (void)usb_proc_explore_msignal(sc->sc_udev,
+ &sc->sc_readout_msg[0], &sc->sc_readout_msg[1]);
+ usb_proc_explore_unlock(sc->sc_udev);
+
+ callout_reset(&sc->sc_callout, 6 * hz, &ugold_timeout, sc);
+}
+
+static int
+ugold_probe(device_t dev)
+{
+ struct usb_attach_arg *uaa;
+
+ uaa = device_get_ivars(dev);
+ if (uaa->usb_mode != USB_MODE_HOST)
+ return (ENXIO);
+ if (uaa->info.bInterfaceClass != UICLASS_HID)
+ return (ENXIO);
+ if (uaa->info.bIfaceIndex != 0)
+ return (ENXIO);
+
+ return (usbd_lookup_id_by_uaa(ugold_devs, sizeof(ugold_devs), uaa));
+}
+
+static int
+ugold_attach(device_t dev)
+{
+ struct ugold_softc *sc = device_get_softc(dev);
+ struct usb_attach_arg *uaa = device_get_ivars(dev);
+ struct sysctl_oid *sensor_tree;
+ uint16_t d_len;
+ void *d_ptr;
+ int error;
+ int i;
+
+ sc->sc_udev = uaa->device;
+ sc->sc_readout_msg[0].hdr.pm_callback = &ugold_readout_msg;
+ sc->sc_readout_msg[0].sc = sc;
+ sc->sc_readout_msg[1].hdr.pm_callback = &ugold_readout_msg;
+ sc->sc_readout_msg[1].sc = sc;
+ sc->sc_iface_index[0] = uaa->info.bIfaceIndex;
+ sc->sc_iface_index[1] = uaa->info.bIfaceIndex + 1;
+
+ device_set_usb_desc(dev);
+ mtx_init(&sc->sc_mtx, "ugold lock", NULL, MTX_DEF | MTX_RECURSE);
+ callout_init_mtx(&sc->sc_callout, &sc->sc_mtx, 0);
+
+ /* grab all interfaces from other drivers */
+ for (i = 0;; i++) {
+ if (i == uaa->info.bIfaceIndex)
+ continue;
+ if (usbd_get_iface(uaa->device, i) == NULL)
+ break;
+
+ usbd_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex);
+ }
+
+ /* figure out report ID */
+ error = usbd_req_get_hid_desc(uaa->device, NULL,
+ &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex);
+
+ if (error)
+ goto detach;
+
+ (void)hid_report_size(d_ptr, d_len, hid_input, &sc->sc_report_id);
+
+ free(d_ptr, M_TEMP);
+
+ error = usbd_transfer_setup(uaa->device,
+ sc->sc_iface_index, sc->sc_xfer, ugold_config,
+ UGOLD_N_TRANSFER, sc, &sc->sc_mtx);
+ if (error)
+ goto detach;
+
+ sensor_tree = SYSCTL_ADD_NODE(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "sensors",
+ CTLFLAG_RD, NULL, "");
+
+ if (sensor_tree == NULL) {
+ error = ENOMEM;
+ goto detach;
+ }
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "inner", CTLFLAG_RD, &sc->sc_sensor[UGOLD_INNER], 0,
+ "Inner temperature in microCelcius");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "inner_valid", CTLFLAG_RD, &sc->sc_valid[UGOLD_INNER], 0,
+ "Inner temperature is valid");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "inner_calib", CTLFLAG_RWTUN, &sc->sc_calib[UGOLD_INNER], 0,
+ "Inner calibration temperature in microCelcius");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "outer", CTLFLAG_RD, &sc->sc_sensor[UGOLD_OUTER], 0,
+ "Outer temperature in microCelcius");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "outer_calib", CTLFLAG_RWTUN, &sc->sc_calib[UGOLD_OUTER], 0,
+ "Outer calibration temperature in microCelcius");
+
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(sensor_tree),
+ OID_AUTO, "outer_valid", CTLFLAG_RD, &sc->sc_valid[UGOLD_OUTER], 0,
+ "Outer temperature is valid");
+
+ mtx_lock(&sc->sc_mtx);
+ usbd_transfer_start(sc->sc_xfer[UGOLD_INTR_DT]);
+ ugold_timeout(sc);
+ mtx_unlock(&sc->sc_mtx);
+
+ return (0);
+
+detach:
+ DPRINTF("error=%s\n", usbd_errstr(error));
+ ugold_detach(dev);
+ return (error);
+}
+
+static int
+ugold_detach(device_t dev)
+{
+ struct ugold_softc *sc = device_get_softc(dev);
+
+ callout_drain(&sc->sc_callout);
+
+ usb_proc_explore_lock(sc->sc_udev);
+ usb_proc_explore_mwait(sc->sc_udev,
+ &sc->sc_readout_msg[0], &sc->sc_readout_msg[1]);
+ usb_proc_explore_unlock(sc->sc_udev);
+
+ usbd_transfer_unsetup(sc->sc_xfer, UGOLD_N_TRANSFER);
+
+ mtx_destroy(&sc->sc_mtx);
+
+ return (0);
+}
+
+static int
+ugold_ds75_temp(uint8_t msb, uint8_t lsb)
+{
+ /* DS75: 12bit precision mode : 0.0625 degrees Celsius ticks */
+ /* NOTE: MSB has a sign bit for negative temperatures */
+ int32_t temp = (msb << 24) | ((lsb & 0xF0) << 16);
+ return (((int64_t)temp * (int64_t)1000000LL) >> 24);
+}
+
+
+static void
+ugold_intr_callback(struct usb_xfer *xfer, usb_error_t error)
+{
+ struct ugold_softc *sc = usbd_xfer_softc(xfer);
+ struct usb_page_cache *pc;
+ uint8_t buf[8];
+ int temp;
+ int len;
+
+ usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
+
+ switch (USB_GET_STATE(xfer)) {
+ case USB_ST_TRANSFERRED:
+ memset(buf, 0, sizeof(buf));
+
+ pc = usbd_xfer_get_frame(xfer, 0);
+ usbd_copy_out(pc, 0, buf, MIN(len, sizeof(buf)));
+
+ switch (buf[0]) {
+ case UGOLD_CMD_INIT:
+ if (sc->sc_num_sensors)
+ break;
+
+ sc->sc_num_sensors = MIN(buf[1], UGOLD_MAX_SENSORS) /* XXX */ ;
+
+ DPRINTF("%d sensor%s type ds75/12bit (temperature)\n",
+ sc->sc_num_sensors, (sc->sc_num_sensors == 1) ? "" : "s");
+ break;
+ case UGOLD_CMD_DATA:
+ switch (buf[1]) {
+ case 4:
+ temp = ugold_ds75_temp(buf[4], buf[5]);
+ sc->sc_sensor[UGOLD_OUTER] = temp + sc->sc_calib[UGOLD_OUTER];
+ sc->sc_valid[UGOLD_OUTER] = 1;
+ /* FALLTHROUGH */
+ case 2:
+ temp = ugold_ds75_temp(buf[2], buf[3]);
+ sc->sc_sensor[UGOLD_INNER] = temp + sc->sc_calib[UGOLD_INNER];
+ sc->sc_valid[UGOLD_INNER] = 1;
+ break;
+ default:
+ DPRINTF("invalid data length (%d bytes)\n", buf[1]);
+ }
+ break;
+ default:
+ DPRINTF("unknown command 0x%02x\n", buf[0]);
+ break;
+ }
+ /* FALLTHROUGH */
+ case USB_ST_SETUP:
+tr_setup:
+ usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
+ usbd_transfer_submit(xfer);
+ break;
+ default: /* Error */
+ if (error != USB_ERR_CANCELLED) {
+ /* try clear stall first */
+ usbd_xfer_set_stall(xfer);
+ goto tr_setup;
+ }
+ break;
+ }
+}
+
+static int
+ugold_issue_cmd(struct ugold_softc *sc, uint8_t *cmd, int len)
+{
+ return (usbd_req_set_report(sc->sc_udev, &sc->sc_mtx, cmd, len,
+ sc->sc_iface_index[1], UHID_OUTPUT_REPORT, sc->sc_report_id));
+}
+
+static void
+ugold_readout_msg(struct usb_proc_msg *pm)
+{
+ struct ugold_softc *sc = ((struct ugold_readout_msg *)pm)->sc;
+
+ usb_proc_explore_unlock(sc->sc_udev);
+
+ mtx_lock(&sc->sc_mtx);
+ if (sc->sc_num_sensors == 0)
+ ugold_issue_cmd(sc, cmd_init, sizeof(cmd_init));
+
+ ugold_issue_cmd(sc, cmd_data, sizeof(cmd_data));
+ mtx_unlock(&sc->sc_mtx);
+
+ usb_proc_explore_lock(sc->sc_udev);
+}
diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index 3cfaef0ddec5..c756b244495d 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -94,6 +94,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(SILICONPORTALS, YAPPHONE, 0x100, 0x100, UQ_AU_INP_ASYNC),
USB_QUIRK(LOGITECH, UN53B, 0x0000, 0xffff, UQ_NO_STRINGS),
USB_QUIRK(REALTEK, RTL8196EU, 0x0000, 0xffff, UQ_CFG_INDEX_1),
+ USB_QUIRK(REALTEK, RTL8153, 0x0000, 0xffff, UQ_CFG_INDEX_1),
USB_QUIRK(ELSA, MODEM1, 0x0000, 0xffff, UQ_CFG_INDEX_1),
USB_QUIRK(PLANEX2, MZKUE150N, 0x0000, 0xffff, UQ_CFG_INDEX_1),
/* Quirks for printer devices */
diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c
index 49bd373a9210..140c0b9b3c23 100644
--- a/sys/dev/usb/template/usb_template.c
+++ b/sys/dev/usb/template/usb_template.c
@@ -1374,6 +1374,9 @@ usb_temp_setup_by_index(struct usb_device *udev, uint16_t index)
case USB_TEMP_SERIALNET:
err = usb_temp_setup(udev, &usb_template_serialnet);
break;
+ case USB_TEMP_MIDI:
+ err = usb_temp_setup(udev, &usb_template_midi);
+ break;
default:
return (USB_ERR_INVAL);
}
diff --git a/sys/dev/usb/template/usb_template.h b/sys/dev/usb/template/usb_template.h
index 484608d3de69..1b320c689f1b 100644
--- a/sys/dev/usb/template/usb_template.h
+++ b/sys/dev/usb/template/usb_template.h
@@ -107,6 +107,7 @@ extern const struct usb_temp_device_desc usb_template_msc;
extern const struct usb_temp_device_desc usb_template_mtp;
extern const struct usb_temp_device_desc usb_template_phone;
extern const struct usb_temp_device_desc usb_template_serialnet;
+extern const struct usb_temp_device_desc usb_template_midi;
usb_error_t usb_temp_setup(struct usb_device *,
const struct usb_temp_device_desc *);
diff --git a/sys/dev/usb/template/usb_template_midi.c b/sys/dev/usb/template/usb_template_midi.c
new file mode 100644
index 000000000000..9be1b9e5a18c
--- /dev/null
+++ b/sys/dev/usb/template/usb_template_midi.c
@@ -0,0 +1,240 @@
+/* $FreeBSD$ */
+/*-
+ * Copyright (c) 2015 Hans Petter Selasky. 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.
+ */
+
+/*
+ * This file contains the USB template for an USB MIDI Device.
+ */
+
+#ifdef USB_GLOBAL_INCLUDE_FILE
+#include USB_GLOBAL_INCLUDE_FILE
+#else
+#include <sys/stdint.h>
+#include <sys/stddef.h>
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/unistd.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/priv.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usb_core.h>
+
+#include <dev/usb/template/usb_template.h>
+#endif /* USB_GLOBAL_INCLUDE_FILE */
+
+enum {
+ INDEX_MIDI_LANG,
+ INDEX_MIDI_IF,
+ INDEX_MIDI_PRODUCT,
+ INDEX_MIDI_MAX,
+};
+
+#define STRING_MIDI_PRODUCT \
+ "M\0I\0D\0I\0 \0T\0e\0s\0t\0 \0D\0e\0v\0i\0c\0e"
+
+#define STRING_MIDI_IF \
+ "M\0I\0D\0I\0 \0i\0n\0t\0e\0r\0f\0a\0c\0e"
+
+/* make the real string descriptors */
+
+USB_MAKE_STRING_DESC(STRING_MIDI_IF, string_midi_if);
+USB_MAKE_STRING_DESC(STRING_MIDI_PRODUCT, string_midi_product);
+
+/* prototypes */
+
+static const uint8_t midi_desc_raw_0[9] = {
+ 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01
+};
+
+static const void *midi_descs_0[] = {
+ &midi_desc_raw_0,
+ NULL
+};
+
+static const struct usb_temp_interface_desc midi_iface_0 = {
+ .ppEndpoints = NULL, /* no endpoints */
+ .ppRawDesc = midi_descs_0,
+ .bInterfaceClass = 1,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .iInterface = INDEX_MIDI_IF,
+};
+
+static const struct usb_temp_packet_size midi_mps = {
+ .mps[USB_SPEED_LOW] = 8,
+ .mps[USB_SPEED_FULL] = 64,
+ .mps[USB_SPEED_HIGH] = 512,
+};
+
+static const uint8_t midi_desc_raw_7[5] = {
+ 0x05, 0x25, 0x01, 0x01, 0x01
+};
+
+static const void *midi_descs_2[] = {
+ &midi_desc_raw_7,
+ NULL
+};
+
+static const struct usb_temp_endpoint_desc midi_bulk_out_ep = {
+ .ppRawDesc = midi_descs_2,
+ .pPacketSize = &midi_mps,
+ .bEndpointAddress = UE_DIR_OUT,
+ .bmAttributes = UE_BULK,
+};
+
+static const uint8_t midi_desc_raw_6[5] = {
+ 0x05, 0x25, 0x01, 0x01, 0x03,
+};
+
+static const void *midi_descs_3[] = {
+ &midi_desc_raw_6,
+ NULL
+};
+
+static const struct usb_temp_endpoint_desc midi_bulk_in_ep = {
+ .ppRawDesc = midi_descs_3,
+ .pPacketSize = &midi_mps,
+ .bEndpointAddress = UE_DIR_IN,
+ .bmAttributes = UE_BULK,
+};
+
+static const struct usb_temp_endpoint_desc *midi_iface_1_ep[] = {
+ &midi_bulk_out_ep,
+ &midi_bulk_in_ep,
+ NULL,
+};
+
+static const uint8_t midi_desc_raw_1[7] = {
+ 0x07, 0x24, 0x01, 0x00, 0x01, /* wTotalLength: */ 0x41, 0x00
+};
+
+static const uint8_t midi_desc_raw_2[6] = {
+ 0x06, 0x24, 0x02, 0x01, 0x01, 0x00
+};
+
+static const uint8_t midi_desc_raw_3[6] = {
+ 0x06, 0x24, 0x02, 0x02, 0x02, 0x00
+};
+
+static const uint8_t midi_desc_raw_4[9] = {
+ 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00
+};
+
+static const uint8_t midi_desc_raw_5[9] = {
+ 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x01, 0x01, 0x00
+};
+
+static const void *midi_descs_1[] = {
+ &midi_desc_raw_1,
+ &midi_desc_raw_2,
+ &midi_desc_raw_3,
+ &midi_desc_raw_4,
+ &midi_desc_raw_5,
+ NULL
+};
+
+static const struct usb_temp_interface_desc midi_iface_1 = {
+ .ppRawDesc = midi_descs_1,
+ .ppEndpoints = midi_iface_1_ep,
+ .bInterfaceClass = 0x01, /* MIDI */
+ .bInterfaceSubClass = 3, /* MIDI streaming */
+ .bInterfaceProtocol = 0,
+ .iInterface = INDEX_MIDI_IF,
+};
+
+static const struct usb_temp_interface_desc *midi_interfaces[] = {
+ &midi_iface_0,
+ &midi_iface_1,
+ NULL,
+};
+
+static const struct usb_temp_config_desc midi_config_desc = {
+ .ppIfaceDesc = midi_interfaces,
+ .bmAttributes = UC_BUS_POWERED,
+ .bMaxPower = 25, /* 50 mA */
+ .iConfiguration = INDEX_MIDI_PRODUCT,
+};
+
+static const struct usb_temp_config_desc *midi_configs[] = {
+ &midi_config_desc,
+ NULL,
+};
+
+static usb_temp_get_string_desc_t midi_get_string_desc;
+
+const struct usb_temp_device_desc usb_template_midi = {
+ .getStringDesc = &midi_get_string_desc,
+ .ppConfigDesc = midi_configs,
+ .idVendor = USB_TEMPLATE_VENDOR,
+ .idProduct = 0x00BB,
+ .bcdDevice = 0x0100,
+ .bDeviceClass = 0,
+ .bDeviceSubClass = 0,
+ .bDeviceProtocol = 0,
+ .iManufacturer = 0,
+ .iProduct = INDEX_MIDI_PRODUCT,
+ .iSerialNumber = 0,
+};
+
+/*------------------------------------------------------------------------*
+ * midi_get_string_desc
+ *
+ * Return values:
+ * NULL: Failure. No such string.
+ * Else: Success. Pointer to string descriptor is returned.
+ *------------------------------------------------------------------------*/
+static const void *
+midi_get_string_desc(uint16_t lang_id, uint8_t string_index)
+{
+ static const void *ptr[INDEX_MIDI_MAX] = {
+ [INDEX_MIDI_LANG] = &usb_string_lang_en,
+ [INDEX_MIDI_IF] = &string_midi_if,
+ [INDEX_MIDI_PRODUCT] = &string_midi_product,
+ };
+
+ if (string_index == 0) {
+ return (&usb_string_lang_en);
+ }
+ if (lang_id != 0x0409) {
+ return (NULL);
+ }
+ if (string_index < INDEX_MIDI_MAX) {
+ return (ptr[string_index]);
+ }
+ return (NULL);
+}
diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c
index 1076a9fe0da8..c48bfc9967e6 100644
--- a/sys/dev/usb/usb_dev.c
+++ b/sys/dev/usb/usb_dev.c
@@ -830,7 +830,8 @@ usb_fifo_close(struct usb_fifo *f, int fflags)
(!f->flag_iserror)) {
/* wait until all data has been written */
f->flag_sleeping = 1;
- err = cv_wait_sig(&f->cv_io, f->priv_mtx);
+ err = cv_timedwait_sig(&f->cv_io, f->priv_mtx,
+ USB_MS_TO_TICKS(USB_DEFAULT_TIMEOUT));
if (err) {
DPRINTF("signal received\n");
break;
diff --git a/sys/dev/usb/usb_ioctl.h b/sys/dev/usb/usb_ioctl.h
index 539f88118824..683f3e61b858 100644
--- a/sys/dev/usb/usb_ioctl.h
+++ b/sys/dev/usb/usb_ioctl.h
@@ -66,6 +66,7 @@ enum {
USB_TEMP_MOUSE, /* USB Mouse */
USB_TEMP_PHONE, /* USB Phone */
USB_TEMP_SERIALNET, /* USB CDC Ethernet and Modem */
+ USB_TEMP_MIDI, /* USB MIDI */
USB_TEMP_MAX,
};
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index f8ba5b5f2f6e..aaf1d6703489 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -525,7 +525,7 @@ vendor DMI 0x0c0b DMI
vendor CANYON 0x0c10 Canyon
vendor ICOM 0x0c26 Icom Inc.
vendor GNOTOMETRICS 0x0c33 GN Otometrics
-vendor CHICONY2 0x0c45 Chicony
+vendor CHICONY2 0x0c45 Chicony / Microdia / Sonix Technology Co., Ltd.
vendor REINERSCT 0x0c4b Reiner-SCT
vendor SEALEVEL 0x0c52 Sealevel System
vendor JETI 0x0c6c Jeti
@@ -3050,6 +3050,11 @@ product MGE UPS2 0xffff MGE UPS SYSTEMS PROTECTIONCENTER 2
product MEI CASHFLOW_SC 0x1100 Cashflow-SC Cash Acceptor
product MEI S2000 0x1101 Series 2000 Combo Acceptor
+/* Microdia / Sonix Techonology Co., Ltd. products */
+product CHICONY2 YUREX 0x1010 YUREX
+product CHICONY2 CAM_1 0x62c0 CAM_1
+product CHICONY2 TEMPER 0x7401 TEMPer sensor
+
/* Micro Star International products */
product MSI BT_DONGLE 0x1967 Bluetooth USB dongle
product MSI RT3070_1 0x3820 RT3070
@@ -3748,6 +3753,7 @@ product REALTEK USB20CRW 0x0158 USB20CRW Card Reader
product REALTEK RTL8188ETV 0x0179 RTL8188ETV
product REALTEK RTL8188CTV 0x018a RTL8188CTV
product REALTEK USBKR100 0x8150 USBKR100 USB Ethernet
+product REALTEK RTL8153 0x8153 RTL8153 USB Ethernet
product REALTEK RTL8188CE_0 0x8170 RTL8188CE
product REALTEK RTL8171 0x8171 RTL8171
product REALTEK RTL8172 0x8172 RTL8172
diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index 677775c1442a..89b8c0007723 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -142,7 +142,7 @@ static void rsu_vap_delete(struct ieee80211vap *);
static void rsu_scan_start(struct ieee80211com *);
static void rsu_scan_end(struct ieee80211com *);
static void rsu_set_channel(struct ieee80211com *);
-static void rsu_update_mcast(struct ifnet *);
+static void rsu_update_mcast(struct ieee80211com *);
static int rsu_alloc_rx_list(struct rsu_softc *);
static void rsu_free_rx_list(struct rsu_softc *);
static int rsu_alloc_tx_list(struct rsu_softc *);
@@ -355,6 +355,8 @@ rsu_attach(device_t self)
ifp->if_hwassist = CSUM_TCP;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */
ic->ic_opmode = IEEE80211_M_STA; /* Default to BSS mode. */
@@ -532,7 +534,7 @@ rsu_set_channel(struct ieee80211com *ic __unused)
}
static void
-rsu_update_mcast(struct ifnet *ifp)
+rsu_update_mcast(struct ieee80211com *ic)
{
/* XXX do nothing? */
}
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index a3dc5627e6fd..d5142ea8315e 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -201,8 +201,8 @@ static void rum_enable_tsf(struct rum_softc *);
static void rum_update_slot(struct ifnet *);
static void rum_set_bssid(struct rum_softc *, const uint8_t *);
static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
-static void rum_update_mcast(struct ifnet *);
-static void rum_update_promisc(struct ifnet *);
+static void rum_update_mcast(struct ieee80211com *);
+static void rum_update_promisc(struct ieee80211com *);
static void rum_setpromisc(struct rum_softc *);
static const char *rum_get_rf(int);
static void rum_read_eeprom(struct rum_softc *);
@@ -488,6 +488,8 @@ rum_attach(device_t self)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
/* set device capabilities */
@@ -1841,11 +1843,11 @@ rum_setpromisc(struct rum_softc *sc)
}
static void
-rum_update_promisc(struct ifnet *ifp)
+rum_update_promisc(struct ieee80211com *ic)
{
- struct rum_softc *sc = ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
RUM_LOCK(sc);
@@ -1854,12 +1856,12 @@ rum_update_promisc(struct ifnet *ifp)
}
static void
-rum_update_mcast(struct ifnet *ifp)
+rum_update_mcast(struct ieee80211com *ic)
{
static int warning_printed;
if (warning_printed == 0) {
- if_printf(ifp, "need to implement %s\n", __func__);
+ ic_printf(ic, "need to implement %s\n", __func__);
warning_printed = 1;
}
}
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 22cc180f3cbb..ac14178a3c7e 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -439,12 +439,12 @@ static void run_set_basicrates(struct run_softc *);
static void run_set_leds(struct run_softc *, uint16_t);
static void run_set_bssid(struct run_softc *, const uint8_t *);
static void run_set_macaddr(struct run_softc *, const uint8_t *);
-static void run_updateslot(struct ifnet *);
+static void run_updateslot(struct ieee80211com *);
static void run_updateslot_cb(void *);
-static void run_update_mcast(struct ifnet *);
+static void run_update_mcast(struct ieee80211com *);
static int8_t run_rssi2dbm(struct run_softc *, uint8_t, uint8_t);
-static void run_update_promisc_locked(struct ifnet *);
-static void run_update_promisc(struct ifnet *);
+static void run_update_promisc_locked(struct run_softc *);
+static void run_update_promisc(struct ieee80211com *);
static void run_rt5390_bbp_init(struct run_softc *);
static int run_bbp_init(struct run_softc *);
static int run_rt3070_rf_init(struct run_softc *);
@@ -776,6 +776,8 @@ run_attach(device_t self)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
@@ -2137,7 +2139,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
IEEE80211_LOCK(ic);
return (-1);
}
- run_updateslot(ic->ic_ifp);
+ run_updateslot(ic);
run_enable_mrr(sc);
run_set_txpreamble(sc);
run_set_basicrates(sc);
@@ -3785,7 +3787,7 @@ run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
startall = 1;
run_init_locked(sc);
} else
- run_update_promisc_locked(ifp);
+ run_update_promisc_locked(sc);
} else {
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
(ic->ic_nrunning == 0 || sc->rvp_cnt <= 1)) {
@@ -4901,7 +4903,7 @@ run_update_beacon(struct ieee80211vap *vap, int item)
switch (item) {
case IEEE80211_BEACON_ERP:
- run_updateslot(ic->ic_ifp);
+ run_updateslot(ic);
break;
case IEEE80211_BEACON_HTINFO:
run_updateprot(ic);
@@ -5062,33 +5064,32 @@ run_reset_livelock(struct run_softc *sc)
}
static void
-run_update_promisc_locked(struct ifnet *ifp)
+run_update_promisc_locked(struct run_softc *sc)
{
- struct run_softc *sc = ifp->if_softc;
uint32_t tmp;
run_read(sc, RT2860_RX_FILTR_CFG, &tmp);
tmp |= RT2860_DROP_UC_NOME;
- if (ifp->if_flags & IFF_PROMISC)
+ if (sc->sc_ifp->if_flags & IFF_PROMISC)
tmp &= ~RT2860_DROP_UC_NOME;
run_write(sc, RT2860_RX_FILTR_CFG, tmp);
- DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
+ DPRINTF("%s promiscuous mode\n", (sc->sc_ifp->if_flags & IFF_PROMISC) ?
"entering" : "leaving");
}
static void
-run_update_promisc(struct ifnet *ifp)
+run_update_promisc(struct ieee80211com *ic)
{
- struct run_softc *sc = ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
RUN_LOCK(sc);
- run_update_promisc_locked(ifp);
+ run_update_promisc_locked(sc);
RUN_UNLOCK(sc);
}
@@ -5211,16 +5212,15 @@ run_set_macaddr(struct run_softc *sc, const uint8_t *addr)
}
static void
-run_updateslot(struct ifnet *ifp)
+run_updateslot(struct ieee80211com *ic)
{
- struct run_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct run_softc *sc = ic->ic_softc;
uint32_t i;
i = RUN_CMDQ_GET(&sc->cmdq_store);
DPRINTF("cmdq_store=%d\n", i);
sc->cmdq[i].func = run_updateslot_cb;
- sc->cmdq[i].arg0 = ifp;
+ sc->cmdq[i].arg0 = ic->ic_ifp;
ieee80211_runtask(ic, &sc->cmdq_task);
return;
@@ -5242,10 +5242,11 @@ run_updateslot_cb(void *arg)
}
static void
-run_update_mcast(struct ifnet *ifp)
+run_update_mcast(struct ieee80211com *ic)
{
+
/* h/w filter supports getting everything or nothing */
- ifp->if_flags |= IFF_ALLMULTI;
+ ic->ic_ifp->if_flags |= IFF_ALLMULTI;
}
static int8_t
diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index 0796fbe76316..fca9e39a6a27 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -290,8 +290,8 @@ static int uath_raw_xmit(struct ieee80211_node *, struct mbuf *,
static void uath_scan_start(struct ieee80211com *);
static void uath_scan_end(struct ieee80211com *);
static void uath_set_channel(struct ieee80211com *);
-static void uath_update_mcast(struct ifnet *);
-static void uath_update_promisc(struct ifnet *);
+static void uath_update_mcast(struct ieee80211com *);
+static void uath_update_promisc(struct ieee80211com *);
static int uath_config(struct uath_softc *, uint32_t, uint32_t);
static int uath_config_multi(struct uath_softc *, uint32_t, const void *,
int);
@@ -442,6 +442,8 @@ uath_attach(device_t dev)
ic = ifp->if_l2com;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
@@ -1925,13 +1927,13 @@ uath_set_rxmulti_filter(struct uath_softc *sc)
return (0);
}
static void
-uath_update_mcast(struct ifnet *ifp)
+uath_update_mcast(struct ieee80211com *ic)
{
- struct uath_softc *sc = ifp->if_softc;
+ struct uath_softc *sc = ic->ic_softc;
UATH_LOCK(sc);
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
UATH_UNLOCK(sc);
return;
}
@@ -1945,13 +1947,13 @@ uath_update_mcast(struct ifnet *ifp)
}
static void
-uath_update_promisc(struct ifnet *ifp)
+uath_update_promisc(struct ieee80211com *ic)
{
- struct uath_softc *sc = ifp->if_softc;
+ struct uath_softc *sc = ic->ic_softc;
UATH_LOCK(sc);
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
UATH_UNLOCK(sc);
return;
}
diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index 242eb6723909..a2e493ed64fa 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -142,7 +142,7 @@ static struct ieee80211vap *upgt_vap_create(struct ieee80211com *,
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
static void upgt_vap_delete(struct ieee80211vap *);
-static void upgt_update_mcast(struct ifnet *);
+static void upgt_update_mcast(struct ieee80211com *);
static uint8_t upgt_rx_rate(struct upgt_softc *, const int);
static void upgt_set_multi(void *);
static void upgt_stop(struct upgt_softc *);
@@ -341,6 +341,8 @@ upgt_attach(device_t dev)
ic = ifp->if_l2com;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA;
/* set device capabilities */
@@ -1113,9 +1115,9 @@ upgt_vap_delete(struct ieee80211vap *vap)
}
static void
-upgt_update_mcast(struct ifnet *ifp)
+upgt_update_mcast(struct ieee80211com *ic)
{
- struct upgt_softc *sc = ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
upgt_set_multi(sc);
}
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index c81b708be2ae..79a5be0a63f7 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -177,7 +177,7 @@ static void ural_set_basicrates(struct ural_softc *,
const struct ieee80211_channel *);
static void ural_set_bssid(struct ural_softc *, const uint8_t *);
static void ural_set_macaddr(struct ural_softc *, uint8_t *);
-static void ural_update_promisc(struct ifnet *);
+static void ural_update_promisc(struct ieee80211com *);
static void ural_setpromisc(struct ural_softc *);
static const char *ural_get_rf(int);
static void ural_read_eeprom(struct ural_softc *);
@@ -473,6 +473,8 @@ ural_attach(device_t self)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
/* set device capabilities */
@@ -1926,11 +1928,11 @@ ural_setpromisc(struct ural_softc *sc)
}
static void
-ural_update_promisc(struct ifnet *ifp)
+ural_update_promisc(struct ieee80211com *ic)
{
- struct ural_softc *sc = ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
RAL_LOCK(sc);
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index d2c6ef975a9f..f8b77d427521 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -663,7 +663,7 @@ static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
static void urtw_scan_start(struct ieee80211com *);
static void urtw_scan_end(struct ieee80211com *);
static void urtw_set_channel(struct ieee80211com *);
-static void urtw_update_mcast(struct ifnet *);
+static void urtw_update_mcast(struct ieee80211com *);
static int urtw_tx_start(struct urtw_softc *,
struct ieee80211_node *, struct mbuf *,
struct urtw_data *, int);
@@ -758,7 +758,7 @@ static struct urtw_data *
urtw_getbuf(struct urtw_softc *sc);
static int urtw_compute_txtime(uint16_t, uint16_t, uint8_t,
uint8_t);
-static void urtw_updateslot(struct ifnet *);
+static void urtw_updateslot(struct ieee80211com *);
static void urtw_updateslottask(void *, int);
static void urtw_sysctl_node(struct urtw_softc *);
@@ -881,6 +881,8 @@ urtw_attach(device_t dev)
ic = ifp->if_l2com;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
@@ -1661,7 +1663,7 @@ fail:
}
static void
-urtw_update_mcast(struct ifnet *ifp)
+urtw_update_mcast(struct ieee80211com *ic)
{
/* XXX do nothing? */
@@ -4365,10 +4367,9 @@ urtw_compute_txtime(uint16_t framelen, uint16_t rate,
* slot time based on the current setting.
*/
static void
-urtw_updateslot(struct ifnet *ifp)
+urtw_updateslot(struct ieee80211com *ic)
{
- struct urtw_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct urtw_softc *sc = ic->ic_softc;
ieee80211_runtask(ic, &sc->sc_updateslot_task);
}
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index 331f782c368f..6b712b3dbcb6 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -266,7 +266,7 @@ static void urtwn_set_channel(struct ieee80211com *);
static void urtwn_set_chan(struct urtwn_softc *,
struct ieee80211_channel *,
struct ieee80211_channel *);
-static void urtwn_update_mcast(struct ifnet *);
+static void urtwn_update_mcast(struct ieee80211com *);
static void urtwn_iq_calib(struct urtwn_softc *);
static void urtwn_lc_calib(struct urtwn_softc *);
static void urtwn_init(void *);
@@ -442,6 +442,8 @@ urtwn_attach(device_t self)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
@@ -3145,7 +3147,7 @@ urtwn_set_channel(struct ieee80211com *ic)
}
static void
-urtwn_update_mcast(struct ifnet *ifp)
+urtwn_update_mcast(struct ieee80211com *ic)
{
/* XXX do nothing? */
}
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index ca1fb06edb8a..8f9035eaeb0e 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -147,7 +147,7 @@ static int zyd_set_bssid(struct zyd_softc *, const uint8_t *);
static int zyd_switch_radio(struct zyd_softc *, int);
static int zyd_set_led(struct zyd_softc *, int, int);
static void zyd_set_multi(struct zyd_softc *);
-static void zyd_update_mcast(struct ifnet *);
+static void zyd_update_mcast(struct ieee80211com *);
static int zyd_set_rxfilter(struct zyd_softc *);
static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
static int zyd_set_beacon_interval(struct zyd_softc *, int);
@@ -388,6 +388,8 @@ zyd_attach(device_t dev)
ic = ifp->if_l2com;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA;
@@ -2044,11 +2046,11 @@ fail:
}
static void
-zyd_update_mcast(struct ifnet *ifp)
+zyd_update_mcast(struct ieee80211com *ic)
{
- struct zyd_softc *sc = ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
ZYD_LOCK(sc);
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c
index 704a3d95a54d..232d2c9484cd 100644
--- a/sys/dev/virtio/network/if_vtnet.c
+++ b/sys/dev/virtio/network/if_vtnet.c
@@ -443,7 +443,7 @@ vtnet_detach(device_t dev)
sc->vtnet_vlan_attach = NULL;
}
if (sc->vtnet_vlan_detach != NULL) {
- EVENTHANDLER_DEREGISTER(vlan_unconfg, sc->vtnet_vlan_detach);
+ EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vtnet_vlan_detach);
sc->vtnet_vlan_detach = NULL;
}
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index 68018239d736..b316d46dae74 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -127,7 +127,8 @@ static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int);
static int wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state,
int);
static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
- int subtype, int rssi, int nf);
+ int subtype, const struct ieee80211_rx_stats *rxs,
+ int rssi, int nf);
static int wi_reset(struct wi_softc *);
static void wi_watchdog(void *);
static int wi_ioctl(struct ifnet *, u_long, caddr_t);
@@ -143,8 +144,8 @@ static void wi_info_intr(struct wi_softc *);
static int wi_write_txrate(struct wi_softc *, struct ieee80211vap *);
static int wi_write_wep(struct wi_softc *, struct ieee80211vap *);
static int wi_write_multi(struct wi_softc *);
-static void wi_update_mcast(struct ifnet *);
-static void wi_update_promisc(struct ifnet *);
+static void wi_update_mcast(struct ieee80211com *);
+static void wi_update_promisc(struct ieee80211com *);
static int wi_alloc_fid(struct wi_softc *, int, int *);
static void wi_read_nicid(struct wi_softc *);
static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
@@ -344,6 +345,8 @@ wi_attach(device_t dev)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_DS;
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_caps = IEEE80211_C_STA
@@ -803,7 +806,7 @@ wi_scan_end(struct ieee80211com *ic)
static void
wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
@@ -814,7 +817,7 @@ wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
/* NB: filter frames that trigger state changes */
return;
}
- WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, nf);
+ WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
}
static int
@@ -1620,22 +1623,22 @@ allmulti:
}
static void
-wi_update_mcast(struct ifnet *ifp)
+wi_update_mcast(struct ieee80211com *ic)
{
- wi_write_multi(ifp->if_softc);
+
+ wi_write_multi(ic->ic_softc);
}
static void
-wi_update_promisc(struct ifnet *ifp)
+wi_update_promisc(struct ieee80211com *ic)
{
- struct wi_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct wi_softc *sc = ic->ic_softc;
WI_LOCK(sc);
/* XXX handle WEP special case handling? */
wi_write_val(sc, WI_RID_PROMISC,
(ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & IFF_PROMISC)));
+ (ic->ic_ifp->if_flags & IFF_PROMISC)));
WI_UNLOCK(sc);
}
diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h
index 99b866daf10f..f163744ef834 100644
--- a/sys/dev/wi/if_wivar.h
+++ b/sys/dev/wi/if_wivar.h
@@ -61,7 +61,7 @@ struct wi_vap {
struct ieee80211_beacon_offsets wv_bo;
void (*wv_recv_mgmt)(struct ieee80211_node *, struct mbuf *,
- int, int, int);
+ int, const struct ieee80211_rx_stats *rxs, int, int);
int (*wv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 7b438c7024b9..34406059b437 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -177,8 +177,9 @@ static int wpi_add_node_entry_adhoc(struct wpi_softc *);
static struct ieee80211_node *wpi_node_alloc(struct ieee80211vap *,
const uint8_t mac[IEEE80211_ADDR_LEN]);
static void wpi_node_free(struct ieee80211_node *);
-static void wpi_recv_mgmt(struct ieee80211_node *, struct mbuf *, int, int,
- int);
+static void wpi_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
+ const struct ieee80211_rx_stats *,
+ int, int);
static void wpi_restore_node(void *, struct ieee80211_node *);
static void wpi_restore_node_table(struct wpi_softc *, struct wpi_vap *);
static int wpi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
@@ -218,8 +219,8 @@ static int wpi_add_ibss_node(struct wpi_softc *, struct ieee80211_node *);
static void wpi_del_node(struct wpi_softc *, struct ieee80211_node *);
static int wpi_updateedca(struct ieee80211com *);
static void wpi_set_promisc(struct wpi_softc *);
-static void wpi_update_promisc(struct ifnet *);
-static void wpi_update_mcast(struct ifnet *);
+static void wpi_update_promisc(struct ieee80211com *);
+static void wpi_update_mcast(struct ieee80211com *);
static void wpi_set_led(struct wpi_softc *, uint8_t, uint8_t, uint8_t);
static int wpi_set_timing(struct wpi_softc *, struct ieee80211_node *);
static void wpi_power_calibration(struct wpi_softc *);
@@ -452,6 +453,8 @@ wpi_attach(device_t dev)
ic = ifp->if_l2com;
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
@@ -1692,15 +1695,16 @@ wpi_check_bss_filter(struct wpi_softc *sc)
}
static void
-wpi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, int rssi,
- int nf)
+wpi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype,
+ const struct ieee80211_rx_stats *rxs,
+ int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct wpi_softc *sc = vap->iv_ic->ic_ifp->if_softc;
struct wpi_vap *wvp = WPI_VAP(vap);
uint64_t ni_tstamp, rx_tstamp;
- wvp->wv_recv_mgmt(ni, m, subtype, rssi, nf);
+ wvp->wv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
if (vap->iv_opmode == IEEE80211_M_IBSS &&
vap->iv_state == IEEE80211_S_RUN &&
@@ -3538,9 +3542,9 @@ wpi_set_promisc(struct wpi_softc *sc)
}
static void
-wpi_update_promisc(struct ifnet *ifp)
+wpi_update_promisc(struct ieee80211com *ic)
{
- struct wpi_softc *sc = ifp->if_softc;
+ struct wpi_softc *sc = ic->ic_softc;
WPI_RXON_LOCK(sc);
wpi_set_promisc(sc);
@@ -3553,7 +3557,7 @@ wpi_update_promisc(struct ifnet *ifp)
}
static void
-wpi_update_mcast(struct ifnet *ifp)
+wpi_update_mcast(struct ieee80211com *ic)
{
/* Ignore */
}
diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h
index 7a65b721f6c4..b7835281fb39 100644
--- a/sys/dev/wpi/if_wpivar.h
+++ b/sys/dev/wpi/if_wpivar.h
@@ -133,7 +133,9 @@ struct wpi_vap {
int (*wv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
void (*wv_recv_mgmt)(struct ieee80211_node *,
- struct mbuf *, int, int, int);
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *,
+ int, int);
};
#define WPI_VAP(vap) ((struct wpi_vap *)(vap))
diff --git a/sys/dev/wtap/if_wtap.c b/sys/dev/wtap/if_wtap.c
index 3c6408543364..7e2eca783e97 100644
--- a/sys/dev/wtap/if_wtap.c
+++ b/sys/dev/wtap/if_wtap.c
@@ -702,14 +702,14 @@ wtap_wme_update(struct ieee80211com *ic)
}
static void
-wtap_update_mcast(struct ifnet *ifp)
+wtap_update_mcast(struct ieee80211com *ic)
{
DWTAP_PRINTF("%s\n", __func__);
}
static void
-wtap_update_promisc(struct ifnet *ifp)
+wtap_update_promisc(struct ieee80211com *ic)
{
DWTAP_PRINTF("%s\n", __func__);
@@ -797,6 +797,8 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr)
IFQ_SET_READY(&ifp->if_snd);
ic->ic_ifp = ifp;
+ ic->ic_softc = sc;
+ ic->ic_name = sc->name;
ic->ic_phytype = IEEE80211_T_DS;
ic->ic_opmode = IEEE80211_M_MBSS;
ic->ic_caps = IEEE80211_C_MBSS;
@@ -827,9 +829,6 @@ wtap_attach(struct wtap_softc *sc, const uint8_t *macaddr)
/* override default methods */
ic->ic_newassoc = wtap_newassoc;
-#if 0
- ic->ic_updateslot = myath_updateslot;
-#endif
ic->ic_wme.wme_update = wtap_wme_update;
ic->ic_vap_create = wtap_vap_create;
ic->ic_vap_delete = wtap_vap_delete;
diff --git a/sys/dev/wtap/if_wtapvar.h b/sys/dev/wtap/if_wtapvar.h
index bb165b4b203d..3bdc8980b387 100644
--- a/sys/dev/wtap/if_wtapvar.h
+++ b/sys/dev/wtap/if_wtapvar.h
@@ -130,6 +130,7 @@ struct wtap_vap {
struct taskqueue;
struct wtap_softc {
+ char name[7]; /* wtapXX\0 */
int32_t id;
int32_t up;
struct ifnet *sc_ifp; /* interface common */
diff --git a/sys/dev/wtap/wtap_hal/hal.c b/sys/dev/wtap/wtap_hal/hal.c
index 9ec1ca89df7d..6014e3963a6d 100644
--- a/sys/dev/wtap/wtap_hal/hal.c
+++ b/sys/dev/wtap/wtap_hal/hal.c
@@ -182,6 +182,8 @@ new_wtap(struct wtap_hal *hal, int32_t id)
bzero(hal->hal_devs[id], sizeof(struct wtap_softc));
hal->hal_devs[id]->sc_md = hal->hal_md;
hal->hal_devs[id]->id = id;
+ snprintf(hal->hal_devs[id]->name, sizeof(hal->hal_devs[id]->name),
+ "wlan%d", id);
mtx_init(&hal->hal_devs[id]->sc_mtx, "wtap_softc mtx", NULL,
MTX_DEF | MTX_RECURSE);
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c
index d352242d33ed..459271ea26f8 100644
--- a/sys/dev/xen/blkback/blkback.c
+++ b/sys/dev/xen/blkback/blkback.c
@@ -85,11 +85,19 @@ __FBSDID("$FreeBSD$");
/*--------------------------- Compile-time Tunables --------------------------*/
/**
+ * The maximum number of shared memory ring pages we will allow in a
+ * negotiated block-front/back communication channel. Allow enough
+ * ring space for all requests to be XBB_MAX_REQUEST_SIZE'd.
+ */
+#define XBB_MAX_RING_PAGES 32
+
+/**
* The maximum number of outstanding request blocks (request headers plus
* additional segment blocks) we will allow in a negotiated block-front/back
* communication channel.
*/
-#define XBB_MAX_REQUESTS 256
+#define XBB_MAX_REQUESTS \
+ __CONST_RING_SIZE(blkif, PAGE_SIZE * XBB_MAX_RING_PAGES)
/**
* \brief Define to force all I/O to be performed on memory owned by the
@@ -148,14 +156,6 @@ static MALLOC_DEFINE(M_XENBLOCKBACK, "xbbd", "Xen Block Back Driver Data");
(XBB_MAX_REQUEST_SIZE / PAGE_SIZE) + 1)))
/**
- * The maximum number of shared memory ring pages we will allow in a
- * negotiated block-front/back communication channel. Allow enough
- * ring space for all requests to be XBB_MAX_REQUEST_SIZE'd.
- */
-#define XBB_MAX_RING_PAGES \
- BLKIF_RING_PAGES(BLKIF_SEGS_TO_BLOCKS(XBB_MAX_SEGMENTS_PER_REQUEST) \
- * XBB_MAX_REQUESTS)
-/**
* The maximum number of ring pages that we can allow per request list.
* We limit this to the maximum number of segments per request, because
* that is already a reasonable number of segments to aggregate. This
@@ -1328,7 +1328,7 @@ xbb_queue_response(struct xbb_softc *xbb, struct xbb_xen_req *req, int status)
if (status != BLKIF_RSP_OKAY)
xbb->reqs_completed_with_error++;
- xbb->rings.common.rsp_prod_pvt += BLKIF_SEGS_TO_BLOCKS(req->nr_pages);
+ xbb->rings.common.rsp_prod_pvt++;
xbb->reqs_queued_for_completion++;
@@ -1666,87 +1666,49 @@ xbb_dispatch_io(struct xbb_softc *xbb, struct xbb_xen_reqlist *reqlist)
goto send_response;
}
- block_segs = MIN(nreq->nr_pages,
- BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK);
+ block_segs = nseg;
sg = ring_req->seg;
last_block_sg = sg + block_segs;
- while (1) {
-
- while (sg < last_block_sg) {
- KASSERT(seg_idx <
- XBB_MAX_SEGMENTS_PER_REQLIST,
- ("seg_idx %d is too large, max "
- "segs %d\n", seg_idx,
- XBB_MAX_SEGMENTS_PER_REQLIST));
-
- xbb_sg->first_sect = sg->first_sect;
- xbb_sg->last_sect = sg->last_sect;
- xbb_sg->nsect =
- (int8_t)(sg->last_sect -
- sg->first_sect + 1);
-
- if ((sg->last_sect >= (PAGE_SIZE >> 9))
- || (xbb_sg->nsect <= 0)) {
- reqlist->status = BLKIF_RSP_ERROR;
- goto send_response;
- }
-
- nr_sects += xbb_sg->nsect;
- map->host_addr = xbb_get_gntaddr(reqlist,
- seg_idx, /*sector*/0);
- KASSERT(map->host_addr + PAGE_SIZE <=
- xbb->ring_config.gnt_addr,
- ("Host address %#jx len %d overlaps "
- "ring address %#jx\n",
- (uintmax_t)map->host_addr, PAGE_SIZE,
- (uintmax_t)xbb->ring_config.gnt_addr));
-
- map->flags = GNTMAP_host_map;
- map->ref = sg->gref;
- map->dom = xbb->otherend_id;
- if (operation == BIO_WRITE)
- map->flags |= GNTMAP_readonly;
- sg++;
- map++;
- xbb_sg++;
- seg_idx++;
- req_seg_idx++;
- }
- block_segs = MIN(nseg - req_seg_idx,
- BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK);
- if (block_segs == 0)
- break;
-
- /*
- * Fetch the next request block full of SG elements.
- * For now, only the spacing between entries is
- * different in the different ABIs, not the sg entry
- * layout.
- */
- req_ring_idx++;
- switch (xbb->abi) {
- case BLKIF_PROTOCOL_NATIVE:
- sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.native,
- req_ring_idx);
- break;
- case BLKIF_PROTOCOL_X86_32:
- {
- sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.x86_32,
- req_ring_idx);
- break;
- }
- case BLKIF_PROTOCOL_X86_64:
- {
- sg = BLKRING_GET_SEG_BLOCK(&xbb->rings.x86_64,
- req_ring_idx);
- break;
+ while (sg < last_block_sg) {
+ KASSERT(seg_idx <
+ XBB_MAX_SEGMENTS_PER_REQLIST,
+ ("seg_idx %d is too large, max "
+ "segs %d\n", seg_idx,
+ XBB_MAX_SEGMENTS_PER_REQLIST));
+
+ xbb_sg->first_sect = sg->first_sect;
+ xbb_sg->last_sect = sg->last_sect;
+ xbb_sg->nsect =
+ (int8_t)(sg->last_sect -
+ sg->first_sect + 1);
+
+ if ((sg->last_sect >= (PAGE_SIZE >> 9))
+ || (xbb_sg->nsect <= 0)) {
+ reqlist->status = BLKIF_RSP_ERROR;
+ goto send_response;
}
- default:
- panic("Unexpected blkif protocol ABI.");
- /* NOTREACHED */
- }
- last_block_sg = sg + block_segs;
+
+ nr_sects += xbb_sg->nsect;
+ map->host_addr = xbb_get_gntaddr(reqlist,
+ seg_idx, /*sector*/0);
+ KASSERT(map->host_addr + PAGE_SIZE <=
+ xbb->ring_config.gnt_addr,
+ ("Host address %#jx len %d overlaps "
+ "ring address %#jx\n",
+ (uintmax_t)map->host_addr, PAGE_SIZE,
+ (uintmax_t)xbb->ring_config.gnt_addr));
+
+ map->flags = GNTMAP_host_map;
+ map->ref = sg->gref;
+ map->dom = xbb->otherend_id;
+ if (operation == BIO_WRITE)
+ map->flags |= GNTMAP_readonly;
+ sg++;
+ map++;
+ xbb_sg++;
+ seg_idx++;
+ req_seg_idx++;
}
/* Convert to the disk's sector size */
@@ -2000,8 +1962,7 @@ xbb_run_queue(void *context, int pending)
* response be generated before we make room in
* the queue for that response.
*/
- xbb->rings.common.req_cons +=
- BLKIF_SEGS_TO_BLOCKS(ring_req->nr_segments);
+ xbb->rings.common.req_cons++;
xbb->reqs_received++;
cur_size = xbb_count_sects(ring_req);
@@ -3091,7 +3052,7 @@ xbb_collect_frontend_info(struct xbb_softc *xbb)
* Protocol defaults valid even if all negotiation fails.
*/
xbb->ring_config.ring_pages = 1;
- xbb->max_request_segments = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
+ xbb->max_request_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
xbb->max_request_size = xbb->max_request_segments * PAGE_SIZE;
/*
@@ -3122,60 +3083,23 @@ xbb_collect_frontend_info(struct xbb_softc *xbb)
* fields.
*/
ring_page_order = 0;
+ xbb->max_requests = 32;
+
(void)xs_scanf(XST_NIL, otherend_path,
"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",
- &xbb->max_requests);
-
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-request-segments", NULL, "%u",
- &xbb->max_request_segments);
-
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-request-size", NULL, "%u",
- &xbb->max_request_size);
-
if (xbb->ring_config.ring_pages > XBB_MAX_RING_PAGES) {
xenbus_dev_fatal(xbb->dev, EINVAL,
"Front-end specified ring-pages of %u "
- "exceeds backend limit of %zu. "
+ "exceeds backend limit of %u. "
"Unable to connect.",
xbb->ring_config.ring_pages,
XBB_MAX_RING_PAGES);
return (EINVAL);
- } else if (xbb->max_requests > XBB_MAX_REQUESTS) {
- xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specified max_requests of %u "
- "exceeds backend limit of %u. "
- "Unable to connect.",
- xbb->max_requests,
- XBB_MAX_REQUESTS);
- return (EINVAL);
- } else if (xbb->max_request_segments > XBB_MAX_SEGMENTS_PER_REQUEST) {
- xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specified max_requests_segments "
- "of %u exceeds backend limit of %u. "
- "Unable to connect.",
- xbb->max_request_segments,
- XBB_MAX_SEGMENTS_PER_REQUEST);
- return (EINVAL);
- } else if (xbb->max_request_size > XBB_MAX_REQUEST_SIZE) {
- xenbus_dev_fatal(xbb->dev, EINVAL,
- "Front-end specified max_request_size "
- "of %u exceeds backend limit of %u. "
- "Unable to connect.",
- xbb->max_request_size,
- XBB_MAX_REQUEST_SIZE);
- return (EINVAL);
}
if (xbb->ring_config.ring_pages == 1) {
@@ -3723,18 +3647,6 @@ xbb_attach(device_t dev)
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) {
- xbb_attach_failed(xbb, error, "writing %s/max-ring-pages",
- xenbus_get_node(xbb->dev));
- 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);
@@ -3744,32 +3656,6 @@ xbb_attach(device_t dev)
return (error);
}
- error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- "max-requests", "%u", XBB_MAX_REQUESTS);
- if (error) {
- xbb_attach_failed(xbb, error, "writing %s/max-requests",
- xenbus_get_node(xbb->dev));
- return (error);
- }
-
- error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- "max-request-segments", "%u",
- XBB_MAX_SEGMENTS_PER_REQUEST);
- if (error) {
- xbb_attach_failed(xbb, error, "writing %s/max-request-segments",
- xenbus_get_node(xbb->dev));
- return (error);
- }
-
- error = xs_printf(XST_NIL, xenbus_get_node(xbb->dev),
- "max-request-size", "%u",
- XBB_MAX_REQUEST_SIZE);
- if (error) {
- xbb_attach_failed(xbb, error, "writing %s/max-request-size",
- xenbus_get_node(xbb->dev));
- return (error);
- }
-
/* Collect physical device information. */
error = xs_gather(XST_NIL, xenbus_get_otherend_path(xbb->dev),
"device-type", NULL, &xbb->dev_type,
diff --git a/sys/dev/xen/blkfront/blkfront.c b/sys/dev/xen/blkfront/blkfront.c
index 92b5f3542819..a71251df185f 100644
--- a/sys/dev/xen/blkfront/blkfront.c
+++ b/sys/dev/xen/blkfront/blkfront.c
@@ -174,7 +174,6 @@ xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
sc = cm->cm_sc;
if (error) {
- printf("error %d in xbd_queue_cb\n", error);
cm->cm_bp->bio_error = EIO;
biodone(cm->cm_bp);
xbd_free_command(cm);
@@ -191,55 +190,44 @@ xbd_queue_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
ring_req->nr_segments = nsegs;
cm->cm_nseg = nsegs;
- block_segs = MIN(nsegs, BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK);
+ block_segs = MIN(nsegs, BLKIF_MAX_SEGMENTS_PER_REQUEST);
sg = ring_req->seg;
last_block_sg = sg + block_segs;
sg_ref = cm->cm_sg_refs;
- while (1) {
+ while (sg < last_block_sg) {
+ buffer_ma = segs->ds_addr;
+ fsect = (buffer_ma & PAGE_MASK) >> XBD_SECTOR_SHFT;
+ lsect = fsect + (segs->ds_len >> XBD_SECTOR_SHFT) - 1;
- while (sg < last_block_sg) {
- buffer_ma = segs->ds_addr;
- fsect = (buffer_ma & PAGE_MASK) >> XBD_SECTOR_SHFT;
- lsect = fsect + (segs->ds_len >> XBD_SECTOR_SHFT) - 1;
+ KASSERT(lsect <= 7, ("XEN disk driver data cannot "
+ "cross a page boundary"));
- KASSERT(lsect <= 7, ("XEN disk driver data cannot "
- "cross a page boundary"));
+ /* install a grant reference. */
+ ref = gnttab_claim_grant_reference(&cm->cm_gref_head);
- /* install a grant reference. */
- ref = gnttab_claim_grant_reference(&cm->cm_gref_head);
-
- /*
- * GNTTAB_LIST_END == 0xffffffff, but it is private
- * to gnttab.c.
- */
- KASSERT(ref != ~0, ("grant_reference failed"));
-
- gnttab_grant_foreign_access_ref(
- ref,
- xenbus_get_otherend_id(sc->xbd_dev),
- buffer_ma >> PAGE_SHIFT,
- ring_req->operation == BLKIF_OP_WRITE);
-
- *sg_ref = ref;
- *sg = (struct blkif_request_segment) {
- .gref = ref,
- .first_sect = fsect,
- .last_sect = lsect
- };
- sg++;
- sg_ref++;
- segs++;
- nsegs--;
- }
- block_segs = MIN(nsegs, BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK);
- if (block_segs == 0)
- break;
-
- sg = BLKRING_GET_SEG_BLOCK(&sc->xbd_ring,
- sc->xbd_ring.req_prod_pvt);
- sc->xbd_ring.req_prod_pvt++;
- last_block_sg = sg + block_segs;
+ /*
+ * GNTTAB_LIST_END == 0xffffffff, but it is private
+ * to gnttab.c.
+ */
+ KASSERT(ref != ~0, ("grant_reference failed"));
+
+ gnttab_grant_foreign_access_ref(
+ ref,
+ xenbus_get_otherend_id(sc->xbd_dev),
+ buffer_ma >> PAGE_SHIFT,
+ ring_req->operation == BLKIF_OP_WRITE);
+
+ *sg_ref = ref;
+ *sg = (struct blkif_request_segment) {
+ .gref = ref,
+ .first_sect = fsect,
+ .last_sect = lsect
+ };
+ sg++;
+ sg_ref++;
+ segs++;
+ nsegs--;
}
if (cm->cm_operation == BLKIF_OP_READ)
@@ -396,8 +384,8 @@ xbd_startio(struct xbd_softc *sc)
if (sc->xbd_state != XBD_STATE_CONNECTED)
return;
- while (RING_FREE_REQUESTS(&sc->xbd_ring) >=
- sc->xbd_max_request_blocks) {
+ while (!RING_FULL(&sc->xbd_ring)) {
+
if (sc->xbd_qfrozen_cnt != 0)
break;
@@ -450,13 +438,6 @@ xbd_bio_complete(struct xbd_softc *sc, struct xbd_command *cm)
biodone(bp);
}
-static int
-xbd_completion(struct xbd_command *cm)
-{
- gnttab_end_foreign_access_references(cm->cm_nseg, cm->cm_sg_refs);
- return (BLKIF_SEGS_TO_BLOCKS(cm->cm_nseg));
-}
-
static void
xbd_int(void *xsc)
{
@@ -482,7 +463,9 @@ xbd_int(void *xsc)
cm = &sc->xbd_shadow[bret->id];
xbd_remove_cm(cm, XBD_Q_BUSY);
- i += xbd_completion(cm);
+ gnttab_end_foreign_access_references(cm->cm_nseg,
+ cm->cm_sg_refs);
+ i++;
if (cm->cm_operation == BLKIF_OP_READ)
op = BUS_DMASYNC_POSTREAD;
@@ -1064,11 +1047,9 @@ xbd_initialize(struct xbd_softc *sc)
*/
max_ring_page_order = 0;
sc->xbd_ring_pages = 1;
- sc->xbd_max_request_segments = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
+ sc->xbd_max_request_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
sc->xbd_max_request_size =
XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments);
- sc->xbd_max_request_blocks =
- BLKIF_SEGS_TO_BLOCKS(sc->xbd_max_request_segments);
/*
* Protocol negotiation.
@@ -1095,24 +1076,10 @@ xbd_initialize(struct xbd_softc *sc)
if (sc->xbd_ring_pages < 1)
sc->xbd_ring_pages = 1;
- sc->xbd_max_requests =
- BLKIF_MAX_RING_REQUESTS(sc->xbd_ring_pages * PAGE_SIZE);
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-requests", NULL, "%" PRIu32,
- &sc->xbd_max_requests);
-
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-request-segments", NULL, "%" PRIu32,
- &sc->xbd_max_request_segments);
-
- (void)xs_scanf(XST_NIL, otherend_path,
- "max-request-size", NULL, "%" PRIu32,
- &sc->xbd_max_request_size);
-
if (sc->xbd_ring_pages > XBD_MAX_RING_PAGES) {
device_printf(sc->xbd_dev,
"Back-end specified ring-pages of %u "
- "limited to front-end limit of %zu.\n",
+ "limited to front-end limit of %u.\n",
sc->xbd_ring_pages, XBD_MAX_RING_PAGES);
sc->xbd_ring_pages = XBD_MAX_RING_PAGES;
}
@@ -1128,46 +1095,16 @@ xbd_initialize(struct xbd_softc *sc)
sc->xbd_ring_pages = new_page_limit;
}
+ sc->xbd_max_requests =
+ BLKIF_MAX_RING_REQUESTS(sc->xbd_ring_pages * PAGE_SIZE);
if (sc->xbd_max_requests > XBD_MAX_REQUESTS) {
device_printf(sc->xbd_dev,
"Back-end specified max_requests of %u "
- "limited to front-end limit of %u.\n",
+ "limited to front-end limit of %zu.\n",
sc->xbd_max_requests, XBD_MAX_REQUESTS);
sc->xbd_max_requests = XBD_MAX_REQUESTS;
}
- if (sc->xbd_max_request_segments > XBD_MAX_SEGMENTS_PER_REQUEST) {
- device_printf(sc->xbd_dev,
- "Back-end specified max_request_segments of %u "
- "limited to front-end limit of %u.\n",
- sc->xbd_max_request_segments,
- XBD_MAX_SEGMENTS_PER_REQUEST);
- sc->xbd_max_request_segments = XBD_MAX_SEGMENTS_PER_REQUEST;
- }
-
- if (sc->xbd_max_request_size > XBD_MAX_REQUEST_SIZE) {
- device_printf(sc->xbd_dev,
- "Back-end specified max_request_size of %u "
- "limited to front-end limit of %u.\n",
- sc->xbd_max_request_size,
- XBD_MAX_REQUEST_SIZE);
- sc->xbd_max_request_size = XBD_MAX_REQUEST_SIZE;
- }
-
- if (sc->xbd_max_request_size >
- XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments)) {
- device_printf(sc->xbd_dev,
- "Back-end specified max_request_size of %u "
- "limited to front-end limit of %u. (Too few segments.)\n",
- sc->xbd_max_request_size,
- XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments));
- sc->xbd_max_request_size =
- XBD_SEGS_TO_SIZE(sc->xbd_max_request_segments);
- }
-
- sc->xbd_max_request_blocks =
- BLKIF_SEGS_TO_BLOCKS(sc->xbd_max_request_segments);
-
/* Allocate datastructures based on negotiated values. */
error = bus_dma_tag_create(
bus_get_dma_tag(sc->xbd_dev), /* parent */
@@ -1241,36 +1178,6 @@ xbd_initialize(struct xbd_softc *sc)
}
}
- error = xs_printf(XST_NIL, node_path,
- "max-requests","%u",
- sc->xbd_max_requests);
- if (error) {
- xenbus_dev_fatal(sc->xbd_dev, error,
- "writing %s/max-requests",
- node_path);
- return;
- }
-
- error = xs_printf(XST_NIL, node_path,
- "max-request-segments","%u",
- sc->xbd_max_request_segments);
- if (error) {
- xenbus_dev_fatal(sc->xbd_dev, error,
- "writing %s/max-request-segments",
- node_path);
- return;
- }
-
- error = xs_printf(XST_NIL, node_path,
- "max-request-size","%u",
- sc->xbd_max_request_size);
- if (error) {
- xenbus_dev_fatal(sc->xbd_dev, error,
- "writing %s/max-request-size",
- node_path);
- return;
- }
-
error = xs_printf(XST_NIL, node_path, "event-channel",
"%u", xen_intr_port(sc->xen_intr_handle));
if (error) {
diff --git a/sys/dev/xen/blkfront/block.h b/sys/dev/xen/blkfront/block.h
index 9c803bc2eacf..30071189b8ec 100644
--- a/sys/dev/xen/blkfront/block.h
+++ b/sys/dev/xen/blkfront/block.h
@@ -61,11 +61,19 @@
((size / PAGE_SIZE) + 1)
/**
+ * The maximum number of shared memory ring pages we will allow in a
+ * negotiated block-front/back communication channel. Allow enough
+ * ring space for all requests to be XBD_MAX_REQUEST_SIZE'd.
+ */
+#define XBD_MAX_RING_PAGES 32
+
+/**
* The maximum number of outstanding requests blocks (request headers plus
* additional segment blocks) we will allow in a negotiated block-front/back
* communication channel.
*/
-#define XBD_MAX_REQUESTS 256
+#define XBD_MAX_REQUESTS \
+ __CONST_RING_SIZE(blkif, PAGE_SIZE * XBD_MAX_RING_PAGES)
/**
* The maximum mapped region size per request we will allow in a negotiated
@@ -83,15 +91,6 @@
(MIN(BLKIF_MAX_SEGMENTS_PER_REQUEST, \
XBD_SIZE_TO_SEGS(XBD_MAX_REQUEST_SIZE)))
-/**
- * The maximum number of shared memory ring pages we will allow in a
- * negotiated block-front/back communication channel. Allow enough
- * ring space for all requests to be XBD_MAX_REQUEST_SIZE'd.
- */
-#define XBD_MAX_RING_PAGES \
- BLKIF_RING_PAGES(BLKIF_SEGS_TO_BLOCKS(XBD_MAX_SEGMENTS_PER_REQUEST) \
- * XBD_MAX_REQUESTS)
-
typedef enum {
XBDCF_Q_MASK = 0xFF,
/* This command has contributed to xbd_qfrozen_cnt. */
@@ -175,7 +174,6 @@ struct xbd_softc {
u_int xbd_ring_pages;
uint32_t xbd_max_requests;
uint32_t xbd_max_request_segments;
- uint32_t xbd_max_request_blocks;
uint32_t xbd_max_request_size;
grant_ref_t xbd_ring_ref[XBD_MAX_RING_PAGES];
blkif_front_ring_t xbd_ring;
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 552ddd239883..fe8e9ef3f03f 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -51,6 +51,7 @@
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
+#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/priv.h>
@@ -71,6 +72,10 @@ static struct fileops devfs_ops_f;
#include <security/mac/mac_framework.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_object.h>
+
static MALLOC_DEFINE(M_CDEVPDATA, "DEVFSP", "Metainfo for cdev-fp data");
struct mtx devfs_de_interlock;
@@ -1738,6 +1743,65 @@ devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred,
return (error);
}
+static int
+devfs_mmap_f(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
+ vm_prot_t prot, vm_prot_t cap_maxprot, int flags, vm_ooffset_t foff,
+ struct thread *td)
+{
+ struct cdev *dev;
+ struct cdevsw *dsw;
+ struct mount *mp;
+ struct vnode *vp;
+ struct file *fpop;
+ vm_object_t object;
+ vm_prot_t maxprot;
+ int error, ref;
+
+ vp = fp->f_vnode;
+
+ /*
+ * Ensure that file and memory protections are
+ * compatible.
+ */
+ mp = vp->v_mount;
+ if (mp != NULL && (mp->mnt_flag & MNT_NOEXEC) != 0)
+ maxprot = VM_PROT_NONE;
+ else
+ maxprot = VM_PROT_EXECUTE;
+ if ((fp->f_flag & FREAD) != 0)
+ maxprot |= VM_PROT_READ;
+ else if ((prot & VM_PROT_READ) != 0)
+ return (EACCES);
+
+ /*
+ * Character devices always share mappings, so
+ * require a writable fd for writable mappings.
+ */
+ if ((fp->f_flag & FWRITE) != 0)
+ maxprot |= VM_PROT_WRITE;
+ else if ((prot & VM_PROT_WRITE) != 0)
+ return (EACCES);
+ maxprot &= cap_maxprot;
+
+ fpop = td->td_fpop;
+ error = devfs_fp_check(fp, &dev, &dsw, &ref);
+ if (error != 0)
+ return (error);
+
+ error = vm_mmap_cdev(td, size, prot, &maxprot, &flags, dev, dsw, &foff,
+ &object);
+ td->td_fpop = fpop;
+ dev_relthread(dev, ref);
+ if (error != 0)
+ return (error);
+
+ error = vm_mmap_object(map, addr, size, prot, maxprot, flags, object,
+ foff, FALSE, td);
+ if (error != 0)
+ vm_object_deallocate(object);
+ return (error);
+}
+
dev_t
dev2udev(struct cdev *x)
{
@@ -1760,6 +1824,7 @@ static struct fileops devfs_ops_f = {
.fo_sendfile = vn_sendfile,
.fo_seek = vn_seek,
.fo_fill_kinfo = vn_fill_kinfo,
+ .fo_mmap = devfs_mmap_f,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c
index dd30aea279c4..5b8990ee84c4 100644
--- a/sys/fs/ext2fs/ext2_vnops.c
+++ b/sys/fs/ext2fs/ext2_vnops.c
@@ -128,6 +128,7 @@ struct vop_vector ext2_vnodeops = {
.vop_create = ext2_create,
.vop_fsync = ext2_fsync,
.vop_getpages = vnode_pager_local_getpages,
+ .vop_getpages_async = vnode_pager_local_getpages_async,
.vop_getattr = ext2_getattr,
.vop_inactive = ext2_inactive,
.vop_ioctl = ext2_ioctl,
diff --git a/sys/fs/fdescfs/fdesc_vfsops.c b/sys/fs/fdescfs/fdesc_vfsops.c
index d3d8ce01ad2e..f379c5a5aeaf 100644
--- a/sys/fs/fdescfs/fdesc_vfsops.c
+++ b/sys/fs/fdescfs/fdesc_vfsops.c
@@ -199,9 +199,7 @@ fdesc_statfs(mp, sbp)
* limit is ever reduced below the current number
* of open files... ]
*/
- PROC_LOCK(td->td_proc);
- lim = lim_cur(td->td_proc, RLIMIT_NOFILE);
- PROC_UNLOCK(td->td_proc);
+ lim = lim_cur(td, RLIMIT_NOFILE);
fdp = td->td_proc->p_fd;
FILEDESC_SLOCK(fdp);
limit = racct_get_limit(td->td_proc, RACCT_NOFILE);
diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h
index 2ee91457b5a1..be60c1ca7753 100644
--- a/sys/fs/nfs/nfs.h
+++ b/sys/fs/nfs/nfs.h
@@ -138,11 +138,11 @@
/*
* This macro defines the high water mark for issuing V4 delegations.
- * (It is currently set at a conservative 20% of NFSRV_V4STATELIMIT. This
+ * (It is currently set at a conservative 20% of nfsrv_v4statelimit. This
* may want to increase when clients can make more effective use of
* delegations.)
*/
-#define NFSRV_V4DELEGLIMIT(c) (((c) * 5) > NFSRV_V4STATELIMIT)
+#define NFSRV_V4DELEGLIMIT(c) (((c) * 5) > nfsrv_v4statelimit)
#define NFS_READDIRBLKSIZ DIRBLKSIZ /* Minimal nm_readdirsize */
diff --git a/sys/fs/nfs/nfsdport.h b/sys/fs/nfs/nfsdport.h
index efa4b12500ca..a20b55469a71 100644
--- a/sys/fs/nfs/nfsdport.h
+++ b/sys/fs/nfs/nfsdport.h
@@ -88,7 +88,7 @@ struct nfsexstuff {
bcmp(&(f1)->fh_fid, &(f2)->fh_fid, sizeof(struct fid)) == 0)
#define NFSLOCKHASH(f) \
- (&nfslockhash[nfsrv_hashfh(f) % NFSLOCKHASHSIZE])
+ (&nfslockhash[nfsrv_hashfh(f) % nfsrv_lockhashsize])
#define NFSFPVNODE(f) ((struct vnode *)((f)->f_data))
#define NFSFPCRED(f) ((f)->f_cred)
diff --git a/sys/fs/nfs/nfsrvstate.h b/sys/fs/nfs/nfsrvstate.h
index 59a0542c1c9c..972fffe15eb9 100644
--- a/sys/fs/nfs/nfsrvstate.h
+++ b/sys/fs/nfs/nfsrvstate.h
@@ -52,9 +52,9 @@ LIST_HEAD(nfsuserhashhead, nfsusrgrp);
TAILQ_HEAD(nfsuserlruhead, nfsusrgrp);
#define NFSCLIENTHASH(id) \
- (&nfsclienthash[(id).lval[1] % NFSCLIENTHASHSIZE])
+ (&nfsclienthash[(id).lval[1] % nfsrv_clienthashsize])
#define NFSSTATEHASH(clp, id) \
- (&((clp)->lc_stateid[(id).other[2] % NFSSTATEHASHSIZE]))
+ (&((clp)->lc_stateid[(id).other[2] % nfsrv_statehashsize]))
#define NFSUSERHASH(id) \
(&nfsuserhash[(id) % NFSUSERHASHSIZE])
#define NFSUSERNAMEHASH(p, l) \
@@ -71,7 +71,7 @@ struct nfssessionhash {
struct nfssessionhashhead list;
};
#define NFSSESSIONHASH(f) \
- (&nfssessionhash[nfsrv_hashsessionid(f) % NFSSESSIONHASHSIZE])
+ (&nfssessionhash[nfsrv_hashsessionid(f) % nfsrv_sessionhashsize])
/*
* Client server structure for V4. It is doubly linked into two lists.
@@ -81,7 +81,7 @@ struct nfssessionhash {
*/
struct nfsclient {
LIST_ENTRY(nfsclient) lc_hash; /* Clientid hash list */
- struct nfsstatehead lc_stateid[NFSSTATEHASHSIZE]; /* stateid hash */
+ struct nfsstatehead *lc_stateid; /* Stateid hash */
struct nfsstatehead lc_open; /* Open owner list */
struct nfsstatehead lc_deleg; /* Delegations */
struct nfsstatehead lc_olddeleg; /* and old delegations */
@@ -97,10 +97,10 @@ struct nfsclient {
u_int32_t lc_cbref; /* Cnt of callbacks */
uid_t lc_uid; /* User credential */
gid_t lc_gid;
- u_int16_t lc_namelen;
+ u_int16_t lc_idlen; /* Client ID and len */
+ u_int16_t lc_namelen; /* plus GSS principal and len */
u_char *lc_name;
struct nfssockreq lc_req; /* Callback info */
- u_short lc_idlen; /* Length of id string */
u_int32_t lc_flags; /* LCL_ flag bits */
u_char lc_verf[NFSX_VERF]; /* client verifier */
u_char lc_id[1]; /* Malloc'd correct size */
diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c
index f9b8eb8e92e1..0f60686703f7 100644
--- a/sys/fs/nfsserver/nfs_nfsdkrpc.c
+++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c
@@ -294,6 +294,8 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
svc_freereq(rqst);
out:
+ if (softdep_ast_cleanup != NULL)
+ softdep_ast_cleanup();
NFSEXITCODE(0);
}
@@ -464,6 +466,7 @@ int
nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
{
char principal[MAXHOSTNAMELEN + 5];
+ struct proc *p;
int error = 0;
bool_t ret2, ret3, ret4;
@@ -481,6 +484,10 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
*/
NFSD_LOCK();
if (newnfs_numnfsd == 0) {
+ p = td->td_proc;
+ PROC_LOCK(p);
+ p->p_flag2 |= P2_AST_SU;
+ PROC_UNLOCK(p);
newnfs_numnfsd++;
NFSD_UNLOCK();
@@ -512,6 +519,9 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
NFSD_LOCK();
newnfs_numnfsd--;
nfsrvd_init(1);
+ PROC_LOCK(p);
+ p->p_flag2 &= ~P2_AST_SU;
+ PROC_UNLOCK(p);
}
NFSD_UNLOCK();
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 94475d93c66a..85b4466575af 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -58,7 +58,10 @@ extern struct nfsrv_stablefirst nfsrv_stablefirst;
extern void (*nfsd_call_servertimer)(void);
extern SVCPOOL *nfsrvd_pool;
extern struct nfsv4lock nfsd_suspend_lock;
-extern struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE];
+extern struct nfsclienthashhead *nfsclienthash;
+extern struct nfslockhashhead *nfslockhash;
+extern struct nfssessionhash *nfssessionhash;
+extern int nfsrv_sessionhashsize;
struct vfsoptlist nfsv4root_opt, nfsv4root_newopt;
NFSDLOCKMUTEX;
struct nfsrchash_bucket nfsrchash_table[NFSRVCACHE_HASHSIZE];
@@ -3330,9 +3333,6 @@ nfsd_modevent(module_t mod, int type, void *data)
mtx_init(&nfsrc_udpmtx, "nfsuc", NULL, MTX_DEF);
mtx_init(&nfs_v4root_mutex, "nfs4rt", NULL, MTX_DEF);
mtx_init(&nfsv4root_mnt.mnt_mtx, "nfs4mnt", NULL, MTX_DEF);
- for (i = 0; i < NFSSESSIONHASHSIZE; i++)
- mtx_init(&nfssessionhash[i].mtx, "nfssm",
- NULL, MTX_DEF);
lockinit(&nfsv4root_mnt.mnt_explock, PVFS, "explock", 0, 0);
nfsrvd_initcache();
nfsd_init();
@@ -3380,9 +3380,12 @@ nfsd_modevent(module_t mod, int type, void *data)
mtx_destroy(&nfsrc_udpmtx);
mtx_destroy(&nfs_v4root_mutex);
mtx_destroy(&nfsv4root_mnt.mnt_mtx);
- for (i = 0; i < NFSSESSIONHASHSIZE; i++)
+ for (i = 0; i < nfsrv_sessionhashsize; i++)
mtx_destroy(&nfssessionhash[i].mtx);
lockdestroy(&nfsv4root_mnt.mnt_explock);
+ free(nfsclienthash, M_NFSDCLIENT);
+ free(nfslockhash, M_NFSDLOCKFILE);
+ free(nfssessionhash, M_NFSDSESSION);
loaded = 0;
break;
default:
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index bd0c2dad73ad..bd054c47718d 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -53,6 +53,7 @@ extern enum vtype nv34tov_type[8];
extern struct timeval nfsboottime;
extern int nfs_rootfhset;
extern int nfsrv_enable_crossmntpt;
+extern int nfsrv_statehashsize;
#endif /* !APPLEKEXT */
static int nfs_async = 0;
@@ -3468,9 +3469,10 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram,
idlen = i;
if (nd->nd_flag & ND_GSS)
i += nd->nd_princlen;
- MALLOC(clp, struct nfsclient *, sizeof (struct nfsclient) + i,
- M_NFSDCLIENT, M_WAITOK);
- NFSBZERO((caddr_t)clp, sizeof (struct nfsclient) + i);
+ clp = malloc(sizeof(struct nfsclient) + i, M_NFSDCLIENT, M_WAITOK |
+ M_ZERO);
+ clp->lc_stateid = malloc(sizeof(struct nfsstatehead) *
+ nfsrv_statehashsize, M_NFSDCLIENT, M_WAITOK);
NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx);
NFSSOCKADDRALLOC(clp->lc_req.nr_nam);
NFSSOCKADDRSIZE(clp->lc_req.nr_nam, sizeof (struct sockaddr_in));
@@ -3530,7 +3532,8 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram,
if (clp) {
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
- free((caddr_t)clp, M_NFSDCLIENT);
+ free(clp->lc_stateid, M_NFSDCLIENT);
+ free(clp, M_NFSDCLIENT);
}
if (!nd->nd_repstat) {
NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_HYPER);
@@ -3547,7 +3550,8 @@ nfsmout:
if (clp) {
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
- free((caddr_t)clp, M_NFSDCLIENT);
+ free(clp->lc_stateid, M_NFSDCLIENT);
+ free(clp, M_NFSDCLIENT);
}
NFSEXITCODE2(error, nd);
return (error);
@@ -3738,8 +3742,10 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram,
idlen = i;
if (nd->nd_flag & ND_GSS)
i += nd->nd_princlen;
- clp = (struct nfsclient *)malloc(sizeof(struct nfsclient) + i,
- M_NFSDCLIENT, M_WAITOK | M_ZERO);
+ clp = malloc(sizeof(struct nfsclient) + i, M_NFSDCLIENT, M_WAITOK |
+ M_ZERO);
+ clp->lc_stateid = malloc(sizeof(struct nfsstatehead) *
+ nfsrv_statehashsize, M_NFSDCLIENT, M_WAITOK);
NFSINITSOCKMUTEX(&clp->lc_req.nr_mtx);
NFSSOCKADDRALLOC(clp->lc_req.nr_nam);
NFSSOCKADDRSIZE(clp->lc_req.nr_nam, sizeof (struct sockaddr_in));
@@ -3796,6 +3802,7 @@ nfsrvd_exchangeid(struct nfsrv_descript *nd, __unused int isdgram,
if (clp != NULL) {
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
+ free(clp->lc_stateid, M_NFSDCLIENT);
free(clp, M_NFSDCLIENT);
}
if (nd->nd_repstat == 0) {
@@ -3828,6 +3835,7 @@ nfsmout:
if (clp != NULL) {
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
+ free(clp->lc_stateid, M_NFSDCLIENT);
free(clp, M_NFSDCLIENT);
}
NFSEXITCODE2(error, nd);
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index b15dfec4b648..4497161f6dd0 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -46,7 +46,8 @@ extern struct nfsrvfh nfs_pubfh, nfs_rootfh;
extern int nfs_pubfhset, nfs_rootfhset;
extern struct nfsv4lock nfsv4rootfs_lock;
extern struct nfsrv_stablefirst nfsrv_stablefirst;
-extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
+extern struct nfsclienthashhead *nfsclienthash;
+extern int nfsrv_clienthashsize;
extern int nfsrc_floodlevel, nfsrc_tcpsavedreplies;
extern int nfsd_debuglevel;
NFSV4ROOTLOCKMUTEX;
@@ -439,9 +440,12 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram, u_char *tag, int taglen,
if (nd->nd_procnum == NFSPROC_READ ||
nd->nd_procnum == NFSPROC_WRITE ||
nd->nd_procnum == NFSPROC_READDIR ||
+ nd->nd_procnum == NFSPROC_READDIRPLUS ||
nd->nd_procnum == NFSPROC_READLINK ||
nd->nd_procnum == NFSPROC_GETATTR ||
- nd->nd_procnum == NFSPROC_ACCESS)
+ nd->nd_procnum == NFSPROC_ACCESS ||
+ nd->nd_procnum == NFSPROC_FSSTAT ||
+ nd->nd_procnum == NFSPROC_FSINFO)
lktype = LK_SHARED;
else
lktype = LK_EXCLUSIVE;
@@ -543,7 +547,7 @@ static void
nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
int taglen, u_int32_t minorvers, NFSPROC_T *p)
{
- int i, op, op0 = 0;
+ int i, lktype, op, op0 = 0;
u_int32_t *tl;
struct nfsclient *clp, *nclp;
int numops, error = 0, igotlock;
@@ -610,7 +614,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
*/
if (nfsrv_stablefirst.nsf_flags & NFSNSF_EXPIREDCLIENT) {
nfsrv_stablefirst.nsf_flags &= ~NFSNSF_EXPIREDCLIENT;
- for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_clienthashsize; i++) {
LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash,
nclp) {
if (clp->lc_flags & LCL_EXPIREIT) {
@@ -952,11 +956,15 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, u_char *tag,
panic("nfsrvd_compound");
if (nfsv4_opflag[op].needscfh) {
if (vp != NULL) {
- if (nfsv4_opflag[op].modifyfs)
+ lktype = nfsv4_opflag[op].lktype;
+ if (nfsv4_opflag[op].modifyfs) {
vn_start_write(vp, &temp_mp,
V_WAIT);
- if (NFSVOPLOCK(vp, nfsv4_opflag[op].lktype)
- == 0)
+ if (op == NFSV4OP_WRITE &&
+ MNT_SHARED_WRITES(temp_mp))
+ lktype = LK_SHARED;
+ }
+ if (NFSVOPLOCK(vp, lktype) == 0)
VREF(vp);
else
nd->nd_repstat = NFSERR_PERM;
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 5e9beebf0875..15f5243717cf 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -44,14 +44,38 @@ extern u_int32_t newnfs_true, newnfs_false;
NFSV4ROOTLOCKMUTEX;
NFSSTATESPINLOCK;
+SYSCTL_DECL(_vfs_nfsd);
+int nfsrv_statehashsize = NFSSTATEHASHSIZE;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, statehashsize, CTLFLAG_RDTUN,
+ &nfsrv_statehashsize, 0,
+ "Size of state hash table set via loader.conf");
+
+int nfsrv_clienthashsize = NFSCLIENTHASHSIZE;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, clienthashsize, CTLFLAG_RDTUN,
+ &nfsrv_clienthashsize, 0,
+ "Size of client hash table set via loader.conf");
+
+int nfsrv_lockhashsize = NFSLOCKHASHSIZE;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, fhhashsize, CTLFLAG_RDTUN,
+ &nfsrv_lockhashsize, 0,
+ "Size of file handle hash table set via loader.conf");
+
+int nfsrv_sessionhashsize = NFSSESSIONHASHSIZE;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, sessionhashsize, CTLFLAG_RDTUN,
+ &nfsrv_sessionhashsize, 0,
+ "Size of session hash table set via loader.conf");
+
+static int nfsrv_v4statelimit = NFSRV_V4STATELIMIT;
+SYSCTL_INT(_vfs_nfsd, OID_AUTO, v4statelimit, CTLFLAG_RWTUN,
+ &nfsrv_v4statelimit, 0,
+ "High water limit for NFSv4 opens+locks+delegations");
+
/*
* Hash lists for nfs V4.
- * (Some would put them in the .h file, but I don't like declaring storage
- * in a .h)
*/
-struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
-struct nfslockhashhead nfslockhash[NFSLOCKHASHSIZE];
-struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE];
+struct nfsclienthashhead *nfsclienthash;
+struct nfslockhashhead *nfslockhash;
+struct nfssessionhash *nfssessionhash;
#endif /* !APPLEKEXT */
static u_int32_t nfsrv_openpluslock = 0, nfsrv_delegatecnt = 0;
@@ -153,7 +177,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
/*
* Check for state resource limit exceeded.
*/
- if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
+ if (nfsrv_openpluslock > nfsrv_v4statelimit) {
error = NFSERR_RESOURCE;
goto out;
}
@@ -188,7 +212,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
* Search for a match in the client list.
*/
gotit = i = 0;
- while (i < NFSCLIENTHASHSIZE && !gotit) {
+ while (i < nfsrv_clienthashsize && !gotit) {
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
if (new_clp->lc_idlen == clp->lc_idlen &&
!NFSBCMP(new_clp->lc_id, clp->lc_id, clp->lc_idlen)) {
@@ -215,7 +239,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
/*
* Get rid of the old one.
*/
- if (i != NFSCLIENTHASHSIZE) {
+ if (i != nfsrv_clienthashsize) {
LIST_REMOVE(clp, lc_hash);
nfsrv_cleanclient(clp, p);
nfsrv_freedeleglist(&clp->lc_deleg);
@@ -244,7 +268,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
LIST_INIT(&new_clp->lc_deleg);
LIST_INIT(&new_clp->lc_olddeleg);
LIST_INIT(&new_clp->lc_session);
- for (i = 0; i < NFSSTATEHASHSIZE; i++)
+ for (i = 0; i < nfsrv_statehashsize; i++)
LIST_INIT(&new_clp->lc_stateid[i]);
LIST_INSERT_HEAD(NFSCLIENTHASH(new_clp->lc_clientid), new_clp,
lc_hash);
@@ -344,7 +368,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
ls_list);
LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list)
tstp->ls_clp = new_clp;
- for (i = 0; i < NFSSTATEHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_statehashsize; i++) {
LIST_NEWHEAD(&new_clp->lc_stateid[i],
&clp->lc_stateid[i], ls_hash);
LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash)
@@ -405,7 +429,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
LIST_NEWHEAD(&new_clp->lc_olddeleg, &clp->lc_olddeleg, ls_list);
LIST_FOREACH(tstp, &new_clp->lc_olddeleg, ls_list)
tstp->ls_clp = new_clp;
- for (i = 0; i < NFSSTATEHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_statehashsize; i++) {
LIST_NEWHEAD(&new_clp->lc_stateid[i],
&clp->lc_stateid[i], ls_hash);
LIST_FOREACH(tstp, &new_clp->lc_stateid[i], ls_hash)
@@ -615,7 +639,7 @@ nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp,
if (!error && (opflags & CLOPS_RENEWOP)) {
if (nfsrv_notsamecredname(nd, clp)) {
doneok = 0;
- for (i = 0; i < NFSSTATEHASHSIZE && doneok == 0; i++) {
+ for (i = 0; i < nfsrv_statehashsize && doneok == 0; i++) {
LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) {
if ((stp->ls_flags & NFSLCK_OPEN) &&
stp->ls_uid == nd->nd_cred->cr_uid) {
@@ -687,7 +711,7 @@ nfsrv_destroyclient(nfsquad_t clientid, NFSPROC_T *p)
}
/* Scan for state on the clientid. */
- for (i = 0; i < NFSSTATEHASHSIZE; i++)
+ for (i = 0; i < nfsrv_statehashsize; i++)
if (!LIST_EMPTY(&clp->lc_stateid[i])) {
NFSLOCKV4ROOTMUTEX();
nfsv4_unlock(&nfsv4rootfs_lock, 1);
@@ -744,7 +768,7 @@ nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p)
* Search for a match in the client list.
*/
gotit = i = 0;
- while (i < NFSCLIENTHASHSIZE && !gotit) {
+ while (i < nfsrv_clienthashsize && !gotit) {
LIST_FOREACH(clp, &nfsclienthash[i], lc_hash) {
if (revokep->nclid_idlen == clp->lc_idlen &&
!NFSBCMP(revokep->nclid_id, clp->lc_id, clp->lc_idlen)) {
@@ -806,7 +830,7 @@ nfsrv_dumpclients(struct nfsd_dumpclients *dumpp, int maxcnt)
/*
* Rattle through the client lists until done.
*/
- while (i < NFSCLIENTHASHSIZE && cnt < maxcnt) {
+ while (i < nfsrv_clienthashsize && cnt < maxcnt) {
clp = LIST_FIRST(&nfsclienthash[i]);
while (clp != LIST_END(&nfsclienthash[i]) && cnt < maxcnt) {
nfsrv_dumpaclient(clp, &dumpp[cnt]);
@@ -1074,7 +1098,7 @@ nfsrv_servertimer(void)
/*
* For each client...
*/
- for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_clienthashsize; i++) {
clp = LIST_FIRST(&nfsclienthash[i]);
while (clp != LIST_END(&nfsclienthash[i])) {
nclp = LIST_NEXT(clp, lc_hash);
@@ -1085,7 +1109,7 @@ nfsrv_servertimer(void)
nfsrv_clients > nfsrv_clienthighwater)) ||
(clp->lc_expiry + NFSRV_MOULDYLEASE) < NFSD_MONOSEC ||
(clp->lc_expiry < NFSD_MONOSEC &&
- (nfsrv_openpluslock * 10 / 9) > NFSRV_V4STATELIMIT)) {
+ (nfsrv_openpluslock * 10 / 9) > nfsrv_v4statelimit)) {
/*
* Lease has expired several nfsrv_lease times ago:
* PLUS
@@ -1124,7 +1148,7 @@ nfsrv_servertimer(void)
stp->ls_noopens++;
if (stp->ls_noopens > NFSNOOPEN ||
(nfsrv_openpluslock * 2) >
- NFSRV_V4STATELIMIT)
+ nfsrv_v4statelimit)
nfsrv_stablefirst.nsf_flags |=
NFSNSF_NOOPENS;
} else {
@@ -1188,7 +1212,8 @@ nfsrv_zapclient(struct nfsclient *clp, NFSPROC_T *p)
newnfs_disconnect(&clp->lc_req);
NFSSOCKADDRFREE(clp->lc_req.nr_nam);
NFSFREEMUTEX(&clp->lc_req.nr_mtx);
- free((caddr_t)clp, M_NFSDCLIENT);
+ free(clp->lc_stateid, M_NFSDCLIENT);
+ free(clp, M_NFSDCLIENT);
NFSLOCKSTATE();
newnfsstats.srvclients--;
nfsrv_openpluslock--;
@@ -1534,7 +1559,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
* Check for state resource limit exceeded.
*/
if ((new_stp->ls_flags & NFSLCK_LOCK) &&
- nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
+ nfsrv_openpluslock > nfsrv_v4statelimit) {
error = NFSERR_RESOURCE;
goto out;
}
@@ -2232,7 +2257,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
* returns NFSERR_RESOURCE and the limit is just a rather
* arbitrary high water mark, so no harm is done.
*/
- if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
+ if (nfsrv_openpluslock > nfsrv_v4statelimit) {
error = NFSERR_RESOURCE;
goto out;
}
@@ -4298,7 +4323,7 @@ nfsrv_nextstateindex(struct nfsclient *clp)
*/
min_index = 0;
max_index = 0xffffffff;
- for (i = 0; i < NFSSTATEHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_statehashsize; i++) {
LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) {
if (stp->ls_stateid.other[2] > 0x80000000) {
if (stp->ls_stateid.other[2] < max_index)
@@ -4322,7 +4347,7 @@ nfsrv_nextstateindex(struct nfsclient *clp)
* cleanest way to code the loop.)
*/
tryagain:
- for (i = 0; i < NFSSTATEHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_statehashsize; i++) {
LIST_FOREACH(stp, &clp->lc_stateid[i], ls_hash) {
if (stp->ls_stateid.other[2] == canuse) {
canuse++;
@@ -5319,13 +5344,13 @@ nfsrv_throwawayopens(NFSPROC_T *p)
/*
* For each client...
*/
- for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_clienthashsize; i++) {
LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) {
LIST_FOREACH_SAFE(stp, &clp->lc_open, ls_list, nstp) {
if (LIST_EMPTY(&stp->ls_open) &&
(stp->ls_noopens > NFSNOOPEN ||
(nfsrv_openpluslock * 2) >
- NFSRV_V4STATELIMIT))
+ nfsrv_v4statelimit))
nfsrv_freeopenowner(stp, 0, p);
}
}
@@ -5696,11 +5721,12 @@ nfsrv_throwawayallstate(NFSPROC_T *p)
/*
* For each client, clean out the state and then free the structure.
*/
- for (i = 0; i < NFSCLIENTHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_clienthashsize; i++) {
LIST_FOREACH_SAFE(clp, &nfsclienthash[i], lc_hash, nclp) {
nfsrv_cleanclient(clp, p);
nfsrv_freedeleglist(&clp->lc_deleg);
nfsrv_freedeleglist(&clp->lc_olddeleg);
+ free(clp->lc_stateid, M_NFSDCLIENT);
free(clp, M_NFSDCLIENT);
}
}
@@ -5708,7 +5734,7 @@ nfsrv_throwawayallstate(NFSPROC_T *p)
/*
* Also, free up any remaining lock file structures.
*/
- for (i = 0; i < NFSLOCKHASHSIZE; i++) {
+ for (i = 0; i < nfsrv_lockhashsize; i++) {
LIST_FOREACH_SAFE(lfp, &nfslockhash[i], lf_hash, nlfp) {
printf("nfsd unload: fnd a lock file struct\n");
nfsrv_freenfslockfile(lfp);
diff --git a/sys/fs/nfsserver/nfs_nfsdsubs.c b/sys/fs/nfsserver/nfs_nfsdsubs.c
index 6bd141250784..c0421e34ce1f 100644
--- a/sys/fs/nfsserver/nfs_nfsdsubs.c
+++ b/sys/fs/nfsserver/nfs_nfsdsubs.c
@@ -44,9 +44,12 @@ __FBSDID("$FreeBSD$");
extern u_int32_t newnfs_true, newnfs_false;
extern int nfs_pubfhset;
-extern struct nfsclienthashhead nfsclienthash[NFSCLIENTHASHSIZE];
-extern struct nfslockhashhead nfslockhash[NFSLOCKHASHSIZE];
-extern struct nfssessionhash nfssessionhash[NFSSESSIONHASHSIZE];
+extern struct nfsclienthashhead *nfsclienthash;
+extern int nfsrv_clienthashsize;
+extern struct nfslockhashhead *nfslockhash;
+extern int nfsrv_lockhashsize;
+extern struct nfssessionhash *nfssessionhash;
+extern int nfsrv_sessionhashsize;
extern int nfsrv_useacl;
extern uid_t nfsrv_defaultuid;
extern gid_t nfsrv_defaultgid;
@@ -2036,12 +2039,20 @@ nfsd_init(void)
* Initialize client queues. Don't free/reinitialize
* them when nfsds are restarted.
*/
- for (i = 0; i < NFSCLIENTHASHSIZE; i++)
+ nfsclienthash = malloc(sizeof(struct nfsclienthashhead) *
+ nfsrv_clienthashsize, M_NFSDCLIENT, M_WAITOK | M_ZERO);
+ for (i = 0; i < nfsrv_clienthashsize; i++)
LIST_INIT(&nfsclienthash[i]);
- for (i = 0; i < NFSLOCKHASHSIZE; i++)
+ nfslockhash = malloc(sizeof(struct nfslockhashhead) *
+ nfsrv_lockhashsize, M_NFSDLOCKFILE, M_WAITOK | M_ZERO);
+ for (i = 0; i < nfsrv_lockhashsize; i++)
LIST_INIT(&nfslockhash[i]);
- for (i = 0; i < NFSSESSIONHASHSIZE; i++)
+ nfssessionhash = malloc(sizeof(struct nfssessionhash) *
+ nfsrv_sessionhashsize, M_NFSDSESSION, M_WAITOK | M_ZERO);
+ for (i = 0; i < nfsrv_sessionhashsize; i++) {
+ mtx_init(&nfssessionhash[i].mtx, "nfssm", NULL, MTX_DEF);
LIST_INIT(&nfssessionhash[i].list);
+ }
/* and the v2 pubfh should be all zeros */
NFSBZERO(nfs_v2pubfh, NFSX_V2FH);
diff --git a/sys/fs/procfs/procfs_ctl.c b/sys/fs/procfs/procfs_ctl.c
index 1437644d5fa3..15679e36da32 100644
--- a/sys/fs/procfs/procfs_ctl.c
+++ b/sys/fs/procfs/procfs_ctl.c
@@ -235,6 +235,7 @@ out:
} else
PROC_LOCK(p);
p->p_oppid = 0;
+ p->p_stops = 0;
p->p_flag &= ~P_WAITED; /* XXX ? */
sx_xunlock(&proctree_lock);
diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
index eae70229e6bd..b00aac3ac891 100644
--- a/sys/fs/procfs/procfs_map.c
+++ b/sys/fs/procfs/procfs_map.c
@@ -159,11 +159,11 @@ procfs_doprocmap(PFS_FILL_ARGS)
freepath = NULL;
fullpath = "-";
if (lobj) {
+ vp = NULL;
switch (lobj->type) {
default:
case OBJT_DEFAULT:
type = "default";
- vp = NULL;
break;
case OBJT_VNODE:
type = "vnode";
@@ -171,13 +171,19 @@ procfs_doprocmap(PFS_FILL_ARGS)
vref(vp);
break;
case OBJT_SWAP:
- type = "swap";
- vp = NULL;
+ if ((lobj->flags & OBJ_TMPFS_NODE) != 0) {
+ type = "vnode";
+ if ((lobj->flags & OBJ_TMPFS) != 0) {
+ vp = lobj->un_pager.swp.swp_tmpfs;
+ vref(vp);
+ }
+ } else {
+ type = "swap";
+ }
break;
case OBJT_SG:
case OBJT_DEVICE:
type = "device";
- vp = NULL;
break;
}
if (lobj != obj)
diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c
index d7894af61a99..1824d0b005e2 100644
--- a/sys/fs/pseudofs/pseudofs.c
+++ b/sys/fs/pseudofs/pseudofs.c
@@ -52,9 +52,11 @@ static MALLOC_DEFINE(M_PFSNODES, "pfs_nodes", "pseudofs nodes");
SYSCTL_NODE(_vfs, OID_AUTO, pfs, CTLFLAG_RW, 0,
"pseudofs");
+#ifdef PSEUDOFS_TRACE
int pfs_trace;
SYSCTL_INT(_vfs_pfs, OID_AUTO, trace, CTLFLAG_RW, &pfs_trace, 0,
"enable tracing of pseudofs vnode operations");
+#endif
#if PFS_FSNAMELEN != MFSNAMELEN
#error "PFS_FSNAMELEN is not equal to MFSNAMELEN"
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 2e3558238527..5e2a825b012f 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -1320,7 +1320,7 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr)
struct tmpfs_mount *tmp;
struct tmpfs_node *node;
vm_object_t uobj;
- vm_page_t m, ma[1];
+ vm_page_t m;
vm_pindex_t idx, newpages, oldpages;
off_t oldsize;
int base, rv;
@@ -1367,11 +1367,9 @@ retry:
VM_WAIT;
VM_OBJECT_WLOCK(uobj);
goto retry;
- } else if (m->valid != VM_PAGE_BITS_ALL) {
- ma[0] = m;
- rv = vm_pager_get_pages(uobj, ma, 1, 0);
- m = vm_page_lookup(uobj, idx);
- } else
+ } else if (m->valid != VM_PAGE_BITS_ALL)
+ rv = vm_pager_get_pages(uobj, &m, 1, 0);
+ else
/* A cached page was reactivated. */
rv = VM_PAGER_OK;
vm_page_lock(m);
diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c
index e4b9fb50681d..f65ee8c248e7 100644
--- a/sys/fs/unionfs/union_vfsops.c
+++ b/sys/fs/unionfs/union_vfsops.c
@@ -291,18 +291,11 @@ unionfs_domount(struct mount *mp)
}
MNT_ILOCK(mp);
- /*
- * Check mnt_flag
- */
if ((ump->um_lowervp->v_mount->mnt_flag & MNT_LOCAL) &&
(ump->um_uppervp->v_mount->mnt_flag & MNT_LOCAL))
mp->mnt_flag |= MNT_LOCAL;
- /*
- * Check mnt_kern_flag
- */
- if ((ump->um_lowervp->v_mount->mnt_flag & MNTK_SUSPENDABLE) ||
- (ump->um_uppervp->v_mount->mnt_flag & MNTK_SUSPENDABLE))
+ if ((ump->um_uppervp->v_mount->mnt_kern_flag & MNTK_SUSPENDABLE) != 0)
mp->mnt_kern_flag |= MNTK_SUSPENDABLE;
MNT_IUNLOCK(mp);
diff --git a/sys/geom/part/g_part_gpt.c b/sys/geom/part/g_part_gpt.c
index 81ddfa27d82b..08a31983a134 100644
--- a/sys/geom/part/g_part_gpt.c
+++ b/sys/geom/part/g_part_gpt.c
@@ -760,7 +760,7 @@ g_part_gpt_resize(struct g_part_table *basetable,
struct g_part_gpt_entry *entry;
if (baseentry == NULL)
- return (EOPNOTSUPP);
+ return (g_part_gpt_recover(basetable));
entry = (struct g_part_gpt_entry *)baseentry;
baseentry->gpe_end = baseentry->gpe_start + gpp->gpp_size - 1;
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index e5710bfb86e3..1bf81639f057 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -17,6 +17,23 @@ profile 2
#
options KDTRACE_HOOKS
+# DTrace core
+# NOTE: introduces CDDL-licensed components into the kernel
+#device dtrace
+
+# DTrace modules
+#device dtrace_lockstat
+#device dtrace_profile
+#device dtrace_sdt
+#device dtrace_fbt
+#device dtrace_systrace
+#device dtrace_prototype
+#device dtnfscl
+#device dtmalloc
+
+# Alternatively include all the DTrace modules
+#device dtraceall
+
#####################################################################
# SMP OPTIONS:
diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c
index 8cd4440cabf6..03ab10f17dc7 100644
--- a/sys/i386/i386/elf_machdep.c
+++ b/sys/i386/i386/elf_machdep.c
@@ -88,6 +88,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index 39a8828e10ab..70c6d9d00758 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -157,9 +157,12 @@ IDTVEC(xmm)
.type alltraps,@function
alltraps:
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
alltraps_with_regs_pushed:
SET_KERNEL_SREGS
cld
@@ -233,9 +236,12 @@ IDTVEC(lcall_syscall)
pushl $7 /* sizeof "lcall 7,0" */
subl $4,%esp /* skip over tf_trapno */
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
SET_KERNEL_SREGS
cld
FAKE_MCOUNT(TF_EIP(%esp))
@@ -259,9 +265,12 @@ IDTVEC(int0x80_syscall)
pushl $2 /* sizeof "int 0x80" */
subl $4,%esp /* skip over tf_trapno */
pushal
- pushl %ds
- pushl %es
- pushl %fs
+ pushl $0
+ movl %ds,(%esp)
+ pushl $0
+ movl %es,(%esp)
+ pushl $0
+ movl %fs,(%esp)
SET_KERNEL_SREGS
cld
FAKE_MCOUNT(TF_EIP(%esp))
@@ -416,13 +425,16 @@ doreti_iret:
doreti_iret_fault:
subl $8,%esp
pushal
- pushl %ds
+ pushl $0
+ movl %ds,(%esp)
.globl doreti_popl_ds_fault
doreti_popl_ds_fault:
- pushl %es
+ pushl $0
+ movl %es,(%esp)
.globl doreti_popl_es_fault
doreti_popl_es_fault:
- pushl %fs
+ pushl $0
+ movl %fs,(%esp)
.globl doreti_popl_fs_fault
doreti_popl_fs_fault:
sti
diff --git a/sys/i386/i386/gdb_machdep.c b/sys/i386/i386/gdb_machdep.c
index a42b2b63402d..06809ad2a4b8 100644
--- a/sys/i386/i386/gdb_machdep.c
+++ b/sys/i386/i386/gdb_machdep.c
@@ -45,14 +45,22 @@ __FBSDID("$FreeBSD$");
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
+ static uint32_t _kcodesel = GSEL(GCODE_SEL, SEL_KPL);
+ static uint32_t _kdatasel = GSEL(GDATA_SEL, SEL_KPL);
+ static uint32_t _kprivsel = GSEL(GPRIV_SEL, SEL_KPL);
*regsz = gdb_cpu_regsz(regnum);
- if (kdb_thread == curthread) {
+ if (kdb_thread == curthread) {
switch (regnum) {
case 0: return (&kdb_frame->tf_eax);
case 1: return (&kdb_frame->tf_ecx);
case 2: return (&kdb_frame->tf_edx);
+ case 9: return (&kdb_frame->tf_eflags);
+ case 10: return (&kdb_frame->tf_cs);
+ case 12: return (&kdb_frame->tf_ds);
+ case 13: return (&kdb_frame->tf_es);
+ case 14: return (&kdb_frame->tf_fs);
}
}
switch (regnum) {
@@ -62,6 +70,12 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
case 6: return (&kdb_thrctx->pcb_esi);
case 7: return (&kdb_thrctx->pcb_edi);
case 8: return (&kdb_thrctx->pcb_eip);
+ case 10: return (&_kcodesel);
+ case 11: return (&_kdatasel);
+ case 12: return (&_kdatasel);
+ case 13: return (&_kdatasel);
+ case 14: return (&_kprivsel);
+ case 15: return (&kdb_thrctx->pcb_gs);
}
return (NULL);
}
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index 9d8c2653aa43..705d915728fb 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -102,6 +102,7 @@ u_int cpu_mxcsr_mask; /* Valid bits in mxcsr */
#endif
u_int cpu_clflush_line_size = 32;
u_int cpu_stdext_feature;
+u_int cpu_stdext_feature2;
u_int cpu_max_ext_state_size;
u_int cpu_mon_mwait_flags; /* MONITOR/MWAIT flags (CPUID.05H.ECX) */
u_int cpu_mon_min_size; /* MONITOR minimum range size, bytes */
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index a5867c43057a..0373b6fdda90 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -383,10 +383,6 @@ osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
} else
fp = (struct osigframe *)regs->tf_esp - 1;
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
/* Build the argument list for the signal handler. */
sf.sf_signum = sig;
sf.sf_scp = (register_t)&fp->sf_siginfo.si_sc;
@@ -534,10 +530,6 @@ freebsd4_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
} else
sfp = (struct sigframe4 *)regs->tf_esp - 1;
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
/* Build the argument list for the signal handler. */
sf.sf_signum = sig;
sf.sf_ucontext = (register_t)&sfp->sf_uc;
@@ -2875,6 +2867,7 @@ makectx(struct trapframe *tf, struct pcb *pcb)
pcb->pcb_ebx = tf->tf_ebx;
pcb->pcb_eip = tf->tf_eip;
pcb->pcb_esp = (ISPL(tf->tf_cs)) ? tf->tf_esp : (int)(tf + 1) - 8;
+ pcb->pcb_gs = rgs();
}
int
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 029a277b5bea..a642d10088f7 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -4035,6 +4035,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
~PG_W;
dst_pmap->pm_stats.resident_count +=
NBPDR / PAGE_SIZE;
+ pmap_pde_mappings++;
}
continue;
}
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index d783a2bde98c..1e417bfd92bd 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -306,8 +306,8 @@ trap(struct trapframe *frame)
td->td_pticks = 0;
td->td_frame = frame;
addr = frame->tf_eip;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
switch (type) {
case T_PRIVINFLT: /* privileged instruction fault */
@@ -998,12 +998,8 @@ trap_fatal(frame, eva)
if (frame->tf_eflags & PSL_VM)
printf("vm86, ");
printf("IOPL = %d\n", (frame->tf_eflags & PSL_IOPL) >> 12);
- printf("current process = ");
- if (curproc) {
- printf("%lu (%s)\n", (u_long)curproc->p_pid, curthread->td_name);
- } else {
- printf("Idle\n");
- }
+ printf("current process = %d (%s)\n",
+ curproc->p_pid, curthread->td_name);
#ifdef KDB
if (debugger_on_panic || kdb_active) {
diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c
index 2c2cae416c50..c4dba2067cf0 100644
--- a/sys/i386/ibcs2/ibcs2_misc.c
+++ b/sys/i386/ibcs2/ibcs2_misc.c
@@ -98,40 +98,30 @@ ibcs2_ulimit(td, uap)
struct ibcs2_ulimit_args *uap;
{
struct rlimit rl;
- struct proc *p;
int error;
#define IBCS2_GETFSIZE 1
#define IBCS2_SETFSIZE 2
#define IBCS2_GETPSIZE 3
#define IBCS2_GETDTABLESIZE 4
- p = td->td_proc;
switch (uap->cmd) {
case IBCS2_GETFSIZE:
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(p, RLIMIT_FSIZE);
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_FSIZE);
if (td->td_retval[0] == -1)
td->td_retval[0] = 0x7fffffff;
return 0;
case IBCS2_SETFSIZE:
- PROC_LOCK(p);
- rl.rlim_max = lim_max(p, RLIMIT_FSIZE);
- PROC_UNLOCK(p);
+ rl.rlim_max = lim_max(td, RLIMIT_FSIZE);
rl.rlim_cur = uap->newlimit;
error = kern_setrlimit(td, RLIMIT_FSIZE, &rl);
if (!error) {
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(p, RLIMIT_FSIZE);
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_FSIZE);
} else {
DPRINTF(("failed "));
}
return error;
case IBCS2_GETPSIZE:
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(p, RLIMIT_RSS); /* XXX */
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_RSS); /* XXX */
return 0;
case IBCS2_GETDTABLESIZE:
uap->cmd = IBCS2_SC_OPEN_MAX;
@@ -801,18 +791,14 @@ ibcs2_sysconf(td, uap)
struct ibcs2_sysconf_args *uap;
{
int mib[2], value, len, error;
- struct proc *p;
- p = td->td_proc;
switch(uap->name) {
case IBCS2_SC_ARG_MAX:
mib[1] = KERN_ARGMAX;
break;
case IBCS2_SC_CHILD_MAX:
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(td->td_proc, RLIMIT_NPROC);
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_NPROC);
return 0;
case IBCS2_SC_CLK_TCK:
@@ -824,9 +810,7 @@ ibcs2_sysconf(td, uap)
break;
case IBCS2_SC_OPEN_MAX:
- PROC_LOCK(p);
- td->td_retval[0] = lim_cur(td->td_proc, RLIMIT_NOFILE);
- PROC_UNLOCK(p);
+ td->td_retval[0] = lim_cur(td, RLIMIT_NOFILE);
return 0;
case IBCS2_SC_JOB_CONTROL:
diff --git a/sys/i386/ibcs2/ibcs2_sysvec.c b/sys/i386/ibcs2/ibcs2_sysvec.c
index 5d007c7958dd..16507ee2afa3 100644
--- a/sys/i386/ibcs2/ibcs2_sysvec.c
+++ b/sys/i386/ibcs2/ibcs2_sysvec.c
@@ -89,6 +89,7 @@ struct sysentvec ibcs2_svr3_sysvec = {
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = NULL,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
static int
diff --git a/sys/i386/include/asmacros.h b/sys/i386/include/asmacros.h
index 716915c36616..91c25f725dfa 100644
--- a/sys/i386/include/asmacros.h
+++ b/sys/i386/include/asmacros.h
@@ -146,9 +146,12 @@
pushl $0 ; /* dummy error code */ \
pushl $0 ; /* dummy trap type */ \
pushal ; /* 8 ints */ \
- pushl %ds ; /* save data and extra segments ... */ \
- pushl %es ; \
- pushl %fs
+ pushl $0 ; /* save data and extra segments ... */ \
+ mov %ds,(%esp) ; \
+ pushl $0 ; \
+ mov %es,(%esp) ; \
+ pushl $0 ; \
+ mov %fs,(%esp)
#define POP_FRAME \
popl %fs ; \
diff --git a/sys/i386/include/gdb_machdep.h b/sys/i386/include/gdb_machdep.h
index 95af8d4a8f1f..a60ba18d0448 100644
--- a/sys/i386/include/gdb_machdep.h
+++ b/sys/i386/include/gdb_machdep.h
@@ -30,7 +30,7 @@
#define _MACHINE_GDB_MACHDEP_H_
#define GDB_BUFSZ 400
-#define GDB_NREGS 14
+#define GDB_NREGS 16
#define GDB_REG_PC 8
static __inline size_t
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index b5bd35ef524d..633e9c586918 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -49,6 +49,7 @@ extern u_int via_feature_rng;
extern u_int via_feature_xcrypt;
extern u_int cpu_clflush_line_size;
extern u_int cpu_stdext_feature;
+extern u_int cpu_stdext_feature2;
extern u_int cpu_fxsr;
extern u_int cpu_high;
extern u_int cpu_id;
diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h
index cb23b0595649..987ac624abab 100644
--- a/sys/i386/include/vmparam.h
+++ b/sys/i386/include/vmparam.h
@@ -83,13 +83,12 @@
#define VM_PHYSSEG_MAX 17
/*
- * Create two free page pools. Since the i386 kernel virtual address
+ * Create one free page pool. Since the i386 kernel virtual address
* space does not include a mapping onto the machine's entire physical
* memory, VM_FREEPOOL_DIRECT is defined as an alias for the default
* pool, VM_FREEPOOL_DEFAULT.
*/
-#define VM_NFREEPOOL 2
-#define VM_FREEPOOL_CACHE 1
+#define VM_NFREEPOOL 1
#define VM_FREEPOOL_DEFAULT 0
#define VM_FREEPOOL_DIRECT 0
diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c
index 0a4114bc7b14..9363b474b7cc 100644
--- a/sys/i386/linux/imgact_linux.c
+++ b/sys/i386/linux/imgact_linux.c
@@ -108,7 +108,7 @@ exec_linux_imgact(struct image_params *imgp)
*/
PROC_LOCK(imgp->proc);
if (a_out->a_text > maxtsiz ||
- a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA) ||
+ a_out->a_data + bss_size > lim_cur_proc(imgp->proc, RLIMIT_DATA) ||
racct_set(imgp->proc, RACCT_DATA, a_out->a_data + bss_size) != 0) {
PROC_UNLOCK(imgp->proc);
return (ENOMEM);
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h
index 27eff3255c15..36b2084cd9f9 100644
--- a/sys/i386/linux/linux.h
+++ b/sys/i386/linux/linux.h
@@ -33,6 +33,7 @@
#include <sys/signal.h> /* for sigval union */
+#include <compat/linux/linux.h>
#include <i386/linux/linux_syscall.h>
/*
@@ -40,14 +41,12 @@
*/
extern u_char linux_debug_map[];
#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name)
-#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid
-#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid
+#define ARGS(nm, fmt) "linux(%ld/%ld): "#nm"("fmt")\n", \
+ (long)td->td_proc->p_pid, (long)td->td_tid
+#define LMSG(fmt) "linux(%ld/%ld): "fmt"\n", \
+ (long)td->td_proc->p_pid, (long)td->td_tid
#define LINUX_DTRACE linuxulator
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_LINUX);
-#endif
-
#define LINUX_SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE)
#define LINUX_USRSTACK LINUX_SHAREDPAGE
@@ -91,6 +90,7 @@ typedef l_uint l_uid_t;
typedef l_ushort l_uid16_t;
typedef l_int l_timer_t;
typedef l_int l_mqd_t;
+typedef l_ulong l_fd_mask;
typedef struct {
l_int val[2];
@@ -106,7 +106,7 @@ typedef struct {
/*
* Miscellaneous
*/
-#define LINUX_AT_COUNT 16 /* Count of used aux entry types.
+#define LINUX_AT_COUNT 20 /* Count of used aux entry types.
* Keep this synchronized with
* elf_linux_fixup() code.
*/
@@ -235,48 +235,7 @@ struct l_statfs64 {
l_int f_spare[6];
};
-/*
- * Signalling
- */
-#define LINUX_SIGHUP 1
-#define LINUX_SIGINT 2
-#define LINUX_SIGQUIT 3
-#define LINUX_SIGILL 4
-#define LINUX_SIGTRAP 5
-#define LINUX_SIGABRT 6
-#define LINUX_SIGIOT LINUX_SIGABRT
-#define LINUX_SIGBUS 7
-#define LINUX_SIGFPE 8
-#define LINUX_SIGKILL 9
-#define LINUX_SIGUSR1 10
-#define LINUX_SIGSEGV 11
-#define LINUX_SIGUSR2 12
-#define LINUX_SIGPIPE 13
-#define LINUX_SIGALRM 14
-#define LINUX_SIGTERM 15
-#define LINUX_SIGSTKFLT 16
-#define LINUX_SIGCHLD 17
-#define LINUX_SIGCONT 18
-#define LINUX_SIGSTOP 19
-#define LINUX_SIGTSTP 20
-#define LINUX_SIGTTIN 21
-#define LINUX_SIGTTOU 22
-#define LINUX_SIGURG 23
-#define LINUX_SIGXCPU 24
-#define LINUX_SIGXFSZ 25
-#define LINUX_SIGVTALRM 26
-#define LINUX_SIGPROF 27
-#define LINUX_SIGWINCH 28
-#define LINUX_SIGIO 29
-#define LINUX_SIGPOLL LINUX_SIGIO
-#define LINUX_SIGPWR 30
-#define LINUX_SIGSYS 31
-#define LINUX_SIGRTMIN 32
-
-#define LINUX_SIGTBLSZ 31
#define LINUX_NSIG_WORDS 2
-#define LINUX_NBPW 32
-#define LINUX_NSIG (LINUX_NBPW * LINUX_NSIG_WORDS)
/* sigaction flags */
#define LINUX_SA_NOCLDSTOP 0x00000001
@@ -294,27 +253,13 @@ struct l_statfs64 {
#define LINUX_SIG_UNBLOCK 1
#define LINUX_SIG_SETMASK 2
-/* sigset_t macros */
-#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0
-#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig)
-#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig)
-
/* sigaltstack */
#define LINUX_MINSIGSTKSZ 2048
-#define LINUX_SS_ONSTACK 1
-#define LINUX_SS_DISABLE 2
-
-int linux_to_bsd_sigaltstack(int lsa);
-int bsd_to_linux_sigaltstack(int bsa);
typedef void (*l_handler_t)(l_int);
typedef l_ulong l_osigset_t;
typedef struct {
- l_uint __bits[LINUX_NSIG_WORDS];
-} l_sigset_t;
-
-typedef struct {
l_handler_t lsa_handler;
l_osigset_t lsa_mask;
l_ulong lsa_flags;
@@ -497,50 +442,14 @@ struct l_rt_sigframe {
};
extern struct sysentvec linux_sysvec;
-extern struct sysentvec elf_linux_sysvec;
/*
- * open/fcntl flags
+ * arch specific open/fcntl flags
*/
-#define LINUX_O_RDONLY 00000000
-#define LINUX_O_WRONLY 00000001
-#define LINUX_O_RDWR 00000002
-#define LINUX_O_ACCMODE 00000003
-#define LINUX_O_CREAT 00000100
-#define LINUX_O_EXCL 00000200
-#define LINUX_O_NOCTTY 00000400
-#define LINUX_O_TRUNC 00001000
-#define LINUX_O_APPEND 00002000
-#define LINUX_O_NONBLOCK 00004000
-#define LINUX_O_NDELAY LINUX_O_NONBLOCK
-#define LINUX_O_SYNC 00010000
-#define LINUX_FASYNC 00020000
-#define LINUX_O_DIRECT 00040000 /* Direct disk access hint */
-#define LINUX_O_LARGEFILE 00100000
-#define LINUX_O_DIRECTORY 00200000 /* Must be a directory */
-#define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */
-#define LINUX_O_NOATIME 01000000
-#define LINUX_O_CLOEXEC 02000000
-
-#define LINUX_F_DUPFD 0
-#define LINUX_F_GETFD 1
-#define LINUX_F_SETFD 2
-#define LINUX_F_GETFL 3
-#define LINUX_F_SETFL 4
-#define LINUX_F_GETLK 5
-#define LINUX_F_SETLK 6
-#define LINUX_F_SETLKW 7
-#define LINUX_F_SETOWN 8
-#define LINUX_F_GETOWN 9
-
#define LINUX_F_GETLK64 12
#define LINUX_F_SETLK64 13
#define LINUX_F_SETLKW64 14
-#define LINUX_F_RDLCK 0
-#define LINUX_F_WRLCK 1
-#define LINUX_F_UNLCK 2
-
union l_semun {
l_int val;
struct l_semid_ds *buf;
@@ -549,6 +458,16 @@ union l_semun {
void *__pad;
};
+struct l_ipc_perm {
+ l_key_t key;
+ l_uid16_t uid;
+ l_gid16_t gid;
+ l_uid16_t cuid;
+ l_gid16_t cgid;
+ l_ushort mode;
+ l_ushort seq;
+};
+
/*
* Socket defines
*/
@@ -585,22 +504,6 @@ struct l_sockaddr {
char sa_data[14];
};
-struct l_msghdr {
- l_uintptr_t msg_name;
- l_int msg_namelen;
- l_uintptr_t msg_iov;
- l_size_t msg_iovlen;
- l_uintptr_t msg_control;
- l_size_t msg_controllen;
- l_uint msg_flags;
-};
-
-struct l_cmsghdr {
- l_size_t cmsg_len;
- l_int cmsg_level;
- l_int cmsg_type;
-};
-
struct l_ifmap {
l_ulong mem_start;
l_ulong mem_end;
@@ -739,6 +642,8 @@ struct l_desc_struct {
#define LINUX_GET_USEABLE(desc) \
(((desc)->b >> LINUX_ENTRY_B_USEABLE) & 1)
+#define linux_copyout_rusage(r, u) copyout(r, u, sizeof(*r))
+
/* robust futexes */
struct linux_robust_list {
struct linux_robust_list *next;
diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c
index 85d40f0e0911..4c0cad058057 100644
--- a/sys/i386/linux/linux_dummy.c
+++ b/sys/i386/linux/linux_dummy.c
@@ -64,23 +64,18 @@ DUMMY(sysfs);
DUMMY(vm86);
DUMMY(query_module);
DUMMY(nfsservctl);
-DUMMY(rt_sigqueueinfo);
DUMMY(sendfile); /* different semantics */
DUMMY(setfsuid);
DUMMY(setfsgid);
DUMMY(pivot_root);
DUMMY(mincore);
DUMMY(lookup_dcookie);
-DUMMY(epoll_create);
-DUMMY(epoll_ctl);
-DUMMY(epoll_wait);
DUMMY(remap_file_pages);
DUMMY(fstatfs64);
DUMMY(mbind);
DUMMY(get_mempolicy);
DUMMY(set_mempolicy);
DUMMY(kexec_load);
-DUMMY(waitid);
/* linux 2.6.11: */
DUMMY(add_key);
DUMMY(request_key);
@@ -93,8 +88,6 @@ DUMMY(inotify_add_watch);
DUMMY(inotify_rm_watch);
/* linux 2.6.16: */
DUMMY(migrate_pages);
-DUMMY(pselect6);
-DUMMY(ppoll);
DUMMY(unshare);
/* linux 2.6.17: */
DUMMY(splice);
@@ -105,22 +98,14 @@ DUMMY(vmsplice);
DUMMY(move_pages);
/* linux 2.6.19: */
DUMMY(getcpu);
-DUMMY(epoll_pwait);
/* linux 2.6.22: */
-DUMMY(utimensat);
DUMMY(signalfd);
DUMMY(timerfd_create);
-DUMMY(eventfd);
-/* linux 2.6.23: */
-DUMMY(fallocate);
/* linux 2.6.25: */
DUMMY(timerfd_settime);
DUMMY(timerfd_gettime);
/* linux 2.6.27: */
DUMMY(signalfd4);
-DUMMY(eventfd2);
-DUMMY(epoll_create1);
-DUMMY(dup3);
DUMMY(inotify_init1);
/* linux 2.6.30: */
DUMMY(preadv);
@@ -129,17 +114,12 @@ DUMMY(pwritev);
DUMMY(rt_tsigqueueinfo);
DUMMY(perf_event_open);
/* linux 2.6.33: */
-DUMMY(recvmmsg);
DUMMY(fanotify_init);
DUMMY(fanotify_mark);
-/* linux 2.6.36: */
-DUMMY(prlimit64);
/* later: */
DUMMY(name_to_handle_at);
DUMMY(open_by_handle_at);
DUMMY(clock_adjtime);
-DUMMY(syncfs);
-DUMMY(sendmmsg);
DUMMY(setns);
DUMMY(process_vm_readv);
DUMMY(process_vm_writev);
diff --git a/sys/i386/linux/linux_genassym.c b/sys/i386/linux/linux_genassym.c
index 1e845724cfdc..9735110b0472 100644
--- a/sys/i386/linux/linux_genassym.c
+++ b/sys/i386/linux/linux_genassym.c
@@ -6,6 +6,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <i386/linux/linux.h>
+#include <compat/linux/linux_mib.h>
ASSYM(LINUX_SIGF_HANDLER, offsetof(struct l_sigframe, sf_handler));
ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc));
@@ -14,3 +15,5 @@ ASSYM(LINUX_SC_EFLAGS, offsetof(struct l_sigcontext, sc_eflags));
ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler));
ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc));
ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext));
+ASSYM(LINUX_SC_ESP, offsetof(struct l_sigcontext, sc_esp));
+ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE);
diff --git a/sys/i386/linux/linux_locore.s b/sys/i386/linux/linux_locore.s
index a3e0e7dced07..6c4d19c89313 100644
--- a/sys/i386/linux/linux_locore.s
+++ b/sys/i386/linux/linux_locore.s
@@ -5,33 +5,145 @@
#include <i386/linux/linux_syscall.h> /* system call numbers */
+#include "assym.s"
+
+/*
+ * To avoid excess stack frame the signal trampoline code emulates
+ * the 'call' instruction.
+ */
NON_GPROF_ENTRY(linux_sigcode)
- call *LINUX_SIGF_HANDLER(%esp)
- leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */
- mov LINUX_SC_GS(%ebx),%gs
- movl %esp, %ebx /* pass sigframe */
- push %eax /* fake ret addr */
+ movl %esp, %ebx /* preserve sigframe */
+ call .getip0
+.getip0:
+ popl %eax
+ add $.startsigcode-.getip0, %eax /* ret address */
+ push %eax
+ jmp *LINUX_SIGF_HANDLER(%ebx)
+.startsigcode:
+ popl %eax /* gcc unwind code need this */
movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
int $0x80 /* enter kernel with args */
+.endsigcode:
0: jmp 0b
- ALIGN_TEXT
-/* XXXXX */
-linux_rt_sigcode:
- call *LINUX_RT_SIGF_HANDLER(%esp)
+
+NON_GPROF_ENTRY(linux_rt_sigcode)
leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */
leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */
- mov LINUX_SC_GS(%ecx),%gs
- push %eax /* fake ret addr */
+ movl %esp, %edi
+ call .getip1
+.getip1:
+ popl %eax
+ add $.startrtsigcode-.getip1, %eax /* ret address */
+ push %eax
+ jmp *LINUX_RT_SIGF_HANDLER(%edi)
+.startrtsigcode:
movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */
int $0x80 /* enter kernel with args */
+.endrtsigcode:
0: jmp 0b
- ALIGN_TEXT
-/* XXXXX */
-linux_esigcode:
-
- .data
- .globl linux_szsigcode, linux_sznonrtsigcode
-linux_szsigcode:
- .long linux_esigcode-linux_sigcode
-linux_sznonrtsigcode:
- .long linux_rt_sigcode-linux_sigcode
+
+NON_GPROF_ENTRY(linux_vsyscall)
+.startvsyscall:
+ int $0x80
+ ret
+.endvsyscall:
+
+#if 0
+ .section .note.Linux, "a",@note
+ .long 2f - 1f /* namesz */
+ .balign 4
+ .long 4f - 3f /* descsz */
+ .long 0
+1:
+ .asciz "Linux"
+2:
+ .balign 4
+3:
+ .long LINUX_VERSION_CODE
+4:
+ .balign 4
+ .previous
+#endif
+
+#define do_cfa_expr(offset) \
+ .byte 0x0f; /* DW_CFA_def_cfa_expression */ \
+ .uleb128 11f-10f; /* length */ \
+10: .byte 0x74; /* DW_OP_breg4 */ \
+ .sleb128 offset; /* offset */ \
+ .byte 0x06; /* DW_OP_deref */ \
+11:
+
+
+ /* CIE */
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAMEDLSI1:
+ .long .LENDCIEDLSI1-.LSTARTCIEDLSI1
+.LSTARTCIEDLSI1:
+ .long 0 /* CIE ID */
+ .byte 1 /* Version number */
+ .string "zRS" /* NULL-terminated
+ * augmentation string
+ */
+ .uleb128 1 /* Code alignment factor */
+ .sleb128 -4 /* Data alignment factor */
+ .byte 8 /* Return address
+ * register column
+ */
+ .uleb128 1 /* Augmentation value length */
+ .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
+ .byte 0 /* DW_CFA_nop */
+ .align 4
+.LENDCIEDLSI1:
+
+ /* FDE */
+ .long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */
+.LSTARTFDEDLSI1:
+ .long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */
+ .long .startsigcode-. /* PC-relative start address */
+ .long .endsigcode-.startsigcode
+ .uleb128 0 /* Augmentation */
+ do_cfa_expr(LINUX_SIGF_SC-8)
+ .align 4
+.LENDFDEDLSI1:
+
+ .long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */
+.LSTARTFDEDLSI2:
+ .long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */
+ .long .startrtsigcode-. /* PC-relative start address */
+ .long .endrtsigcode-.startrtsigcode
+ .uleb128 0 /* Augmentation */
+ do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP)
+ .align 4
+.LENDFDEDLSI2:
+ .previous
+
+ .section .eh_frame,"a",@progbits
+.LSTARTFRAMEDLSI2:
+ .long .LENDCIEDLSI2-.LSTARTCIEDLSI2
+.LSTARTCIEDLSI2:
+ .long 0 /* CIE ID */
+ .byte 1 /* Version number */
+ .string "zR" /* NULL-terminated
+ * augmentation string
+ */
+ .uleb128 1 /* Code alignment factor */
+ .sleb128 -4 /* Data alignment factor */
+ .byte 8 /* Return address register column */
+ .uleb128 1 /* Augmentation value length */
+ .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
+ .byte 0x0c /* DW_CFA_def_cfa */
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .uleb128 1
+ .align 4
+.LENDCIEDLSI2:
+ .long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */
+.LSTARTFDEDLSI3:
+ .long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */
+ .long .startvsyscall-. /* PC-relative start address */
+ .long .endvsyscall-.startvsyscall
+ .uleb128 0
+ .align 4
+.LENDFDEDLSI3:
+ .previous
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c
index effc32ae9306..4fb5785da4db 100644
--- a/sys/i386/linux/linux_machdep.c
+++ b/sys/i386/linux/linux_machdep.c
@@ -99,35 +99,11 @@ static int linux_mmap_common(struct thread *td, l_uintptr_t addr,
l_size_t len, l_int prot, l_int flags, l_int fd,
l_loff_t pos);
-int
-linux_to_bsd_sigaltstack(int lsa)
-{
- int bsa = 0;
-
- if (lsa & LINUX_SS_DISABLE)
- bsa |= SS_DISABLE;
- if (lsa & LINUX_SS_ONSTACK)
- bsa |= SS_ONSTACK;
- return (bsa);
-}
-
-int
-bsd_to_linux_sigaltstack(int bsa)
-{
- int lsa = 0;
-
- if (bsa & SS_DISABLE)
- lsa |= LINUX_SS_DISABLE;
- if (bsa & SS_ONSTACK)
- lsa |= LINUX_SS_ONSTACK;
- return (lsa);
-}
int
linux_execve(struct thread *td, struct linux_execve_args *args)
{
struct image_args eargs;
- struct vmspace *oldvmspace;
char *newpath;
int error;
@@ -138,26 +114,11 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
printf(ARGS(execve, "%s"), newpath);
#endif
- error = pre_execve(td, &oldvmspace);
- if (error != 0) {
- free(newpath, M_TEMP);
- return (error);
- }
error = exec_copyin_args(&eargs, newpath, UIO_SYSSPACE,
args->argp, args->envp);
free(newpath, M_TEMP);
if (error == 0)
- error = kern_execve(td, &eargs, NULL);
- if (error == 0) {
- /* linux process can exec fbsd one, dont attempt
- * to create emuldata for such process using
- * linux_proc_init, this leads to a panic on KASSERT
- * because such process has p->p_emuldata == NULL
- */
- if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX)
- error = linux_proc_init(td, 0, 0);
- }
- post_execve(td, error, oldvmspace);
+ error = linux_common_execve(td, &eargs);
return (error);
}
@@ -368,8 +329,14 @@ int
linux_set_upcall_kse(struct thread *td, register_t stack)
{
- td->td_frame->tf_esp = stack;
+ if (stack)
+ td->td_frame->tf_esp = stack;
+ /*
+ * The newly created Linux thread returns
+ * to the user space by the same path that a parent do.
+ */
+ td->td_frame->tf_eax = 0;
return (0);
}
@@ -542,7 +509,7 @@ linux_mmap_common(struct thread *td, l_uintptr_t addr, l_size_t len, l_int prot,
*/
PROC_LOCK(p);
p->p_vmspace->vm_maxsaddr = (char *)USRSTACK -
- lim_cur(p, RLIMIT_STACK);
+ lim_cur_proc(p, RLIMIT_STACK);
PROC_UNLOCK(p);
}
@@ -710,7 +677,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
act.lsa_flags = osa.lsa_flags;
act.lsa_restorer = osa.lsa_restorer;
LINUX_SIGEMPTYSET(act.lsa_mask);
- act.lsa_mask.__bits[0] = osa.lsa_mask;
+ act.lsa_mask.__mask = osa.lsa_mask;
}
error = linux_do_sigaction(td, args->sig, args->nsa ? &act : NULL,
@@ -720,7 +687,7 @@ linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
osa.lsa_handler = oact.lsa_handler;
osa.lsa_flags = oact.lsa_flags;
osa.lsa_restorer = oact.lsa_restorer;
- osa.lsa_mask = oact.lsa_mask.__bits[0];
+ osa.lsa_mask = oact.lsa_mask.__mask;
error = copyout(&osa, args->osa, sizeof(l_osigaction_t));
}
@@ -744,7 +711,7 @@ linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args)
#endif
LINUX_SIGEMPTYSET(mask);
- mask.__bits[0] = args->mask;
+ mask.__mask = args->mask;
linux_to_bsd_sigset(&mask, &sigmask);
return (kern_sigsuspend(td, sigmask));
}
@@ -1048,34 +1015,3 @@ linux_mq_getsetattr(struct thread *td, struct linux_mq_getsetattr_args *args)
return (ENOSYS);
#endif
}
-
-int
-linux_wait4(struct thread *td, struct linux_wait4_args *args)
-{
- int error, options;
- struct rusage ru, *rup;
-
-#ifdef DEBUG
- if (ldebug(wait4))
- printf(ARGS(wait4, "%d, %p, %d, %p"),
- args->pid, (void *)args->status, args->options,
- (void *)args->rusage);
-#endif
-
- options = (args->options & (WNOHANG | WUNTRACED));
- /* WLINUXCLONE should be equal to __WCLONE, but we make sure */
- if (args->options & __WCLONE)
- options |= WLINUXCLONE;
-
- if (args->rusage != NULL)
- rup = &ru;
- else
- rup = NULL;
- error = linux_common_wait(td, args->pid, args->status, options, rup);
- if (error)
- return (error);
- if (args->rusage != NULL)
- error = copyout(&ru, args->rusage, sizeof(ru));
-
- return (error);
-}
diff --git a/sys/i386/linux/linux_proto.h b/sys/i386/linux/linux_proto.h
index c542c1de0cab..a5d6ed2e158c 100644
--- a/sys/i386/linux/linux_proto.h
+++ b/sys/i386/linux/linux_proto.h
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/i386/linux/syscalls.master 276509 2015-01-01 18:41:34Z dchagin
+ * created from FreeBSD: head/sys/i386/linux/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
*/
#ifndef _LINUX_SYSPROTO_H_
@@ -35,6 +35,9 @@ struct thread;
#endif
#define nosys linux_nosys
+struct linux_exit_args {
+ char rval_l_[PADL_(int)]; int rval; char rval_r_[PADR_(int)];
+};
struct linux_fork_args {
register_t dummy;
};
@@ -357,7 +360,7 @@ struct linux_wait4_args {
char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
char status_l_[PADL_(l_int *)]; l_int * status; char status_r_[PADR_(l_int *)];
char options_l_[PADL_(l_int)]; l_int options; char options_r_[PADR_(l_int)];
- char rusage_l_[PADL_(struct l_rusage *)]; struct l_rusage * rusage; char rusage_r_[PADR_(struct l_rusage *)];
+ char rusage_l_[PADL_(void *)]; void * rusage; char rusage_r_[PADR_(void *)];
};
struct linux_swapoff_args {
register_t dummy;
@@ -473,6 +476,14 @@ struct linux_fdatasync_args {
struct linux_sysctl_args {
char args_l_[PADL_(struct l___sysctl_args *)]; struct l___sysctl_args * args; char args_r_[PADR_(struct l___sysctl_args *)];
};
+struct linux_sched_setparam_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)];
+};
+struct linux_sched_getparam_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)];
+};
struct linux_sched_setscheduler_args {
char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
@@ -487,6 +498,10 @@ struct linux_sched_get_priority_max_args {
struct linux_sched_get_priority_min_args {
char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
};
+struct linux_sched_rr_get_interval_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char interval_l_[PADL_(struct l_timespec *)]; struct l_timespec * interval; char interval_r_[PADR_(struct l_timespec *)];
+};
struct linux_nanosleep_args {
char rqtp_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * rqtp; char rqtp_r_[PADR_(const struct l_timespec *)];
char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)];
@@ -560,7 +575,9 @@ struct linux_rt_sigtimedwait_args {
char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
};
struct linux_rt_sigqueueinfo_args {
- register_t dummy;
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
+ char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)];
};
struct linux_rt_sigsuspend_args {
char newset_l_[PADL_(l_sigset_t *)]; l_sigset_t * newset; char newset_r_[PADR_(l_sigset_t *)];
@@ -766,13 +783,19 @@ struct linux_lookup_dcookie_args {
register_t dummy;
};
struct linux_epoll_create_args {
- register_t dummy;
+ char size_l_[PADL_(l_int)]; l_int size; char size_r_[PADR_(l_int)];
};
struct linux_epoll_ctl_args {
- register_t dummy;
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char op_l_[PADL_(l_int)]; l_int op; char op_r_[PADR_(l_int)];
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char event_l_[PADL_(struct epoll_event *)]; struct epoll_event * event; char event_r_[PADR_(struct epoll_event *)];
};
struct linux_epoll_wait_args {
- register_t dummy;
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)];
+ char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)];
+ char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)];
};
struct linux_remap_file_pages_args {
register_t dummy;
@@ -887,7 +910,11 @@ struct linux_kexec_load_args {
register_t dummy;
};
struct linux_waitid_args {
- register_t dummy;
+ char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)];
+ char id_l_[PADL_(l_pid_t)]; l_pid_t id; char id_r_[PADR_(l_pid_t)];
+ char info_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * info; char info_r_[PADR_(l_siginfo_t *)];
+ char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)];
+ char rusage_l_[PADL_(void *)]; void * rusage; char rusage_r_[PADR_(void *)];
};
struct linux_add_key_args {
register_t dummy;
@@ -989,13 +1016,21 @@ struct linux_faccessat_args {
char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)];
char amode_l_[PADL_(l_int)]; l_int amode; char amode_r_[PADR_(l_int)];
- char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)];
};
struct linux_pselect6_args {
- register_t dummy;
+ char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)];
+ char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)];
+ char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)];
+ char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)];
+ char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)];
+ char sig_l_[PADL_(l_uintptr_t *)]; l_uintptr_t * sig; char sig_r_[PADR_(l_uintptr_t *)];
};
struct linux_ppoll_args {
- register_t dummy;
+ char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)];
+ char nfds_l_[PADL_(uint32_t)]; uint32_t nfds; char nfds_r_[PADR_(uint32_t)];
+ char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)];
+ char sset_l_[PADL_(l_sigset_t *)]; l_sigset_t * sset; char sset_r_[PADR_(l_sigset_t *)];
+ char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)];
};
struct linux_unshare_args {
register_t dummy;
@@ -1028,10 +1063,17 @@ struct linux_getcpu_args {
register_t dummy;
};
struct linux_epoll_pwait_args {
- register_t dummy;
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)];
+ char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)];
+ char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)];
+ char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
};
struct linux_utimensat_args {
- register_t dummy;
+ char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
+ char pathname_l_[PADL_(const char *)]; const char * pathname; char pathname_r_[PADR_(const char *)];
+ char times_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * times; char times_r_[PADR_(const struct l_timespec *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_signalfd_args {
register_t dummy;
@@ -1040,10 +1082,13 @@ struct linux_timerfd_create_args {
register_t dummy;
};
struct linux_eventfd_args {
- register_t dummy;
+ char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)];
};
struct linux_fallocate_args {
- register_t dummy;
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+ char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+ char len_l_[PADL_(l_loff_t)]; l_loff_t len; char len_r_[PADR_(l_loff_t)];
};
struct linux_timerfd_settime_args {
register_t dummy;
@@ -1055,13 +1100,16 @@ struct linux_signalfd4_args {
register_t dummy;
};
struct linux_eventfd2_args {
- register_t dummy;
+ char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_epoll_create1_args {
- register_t dummy;
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_dup3_args {
- register_t dummy;
+ char oldfd_l_[PADL_(l_int)]; l_int oldfd; char oldfd_r_[PADR_(l_int)];
+ char newfd_l_[PADL_(l_int)]; l_int newfd; char newfd_r_[PADR_(l_int)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_pipe2_args {
char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)];
@@ -1083,7 +1131,11 @@ struct linux_perf_event_open_args {
register_t dummy;
};
struct linux_recvmmsg_args {
- register_t dummy;
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)];
+ char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
+ char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
};
struct linux_fanotify_init_args {
register_t dummy;
@@ -1092,7 +1144,10 @@ struct linux_fanotify_mark_args {
register_t dummy;
};
struct linux_prlimit64_args {
- register_t dummy;
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)];
+ char new_l_[PADL_(struct rlimit *)]; struct rlimit * new; char new_r_[PADR_(struct rlimit *)];
+ char old_l_[PADL_(struct rlimit *)]; struct rlimit * old; char old_r_[PADR_(struct rlimit *)];
};
struct linux_name_to_handle_at_args {
register_t dummy;
@@ -1104,10 +1159,13 @@ struct linux_clock_adjtime_args {
register_t dummy;
};
struct linux_syncfs_args {
- register_t dummy;
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
};
struct linux_sendmmsg_args {
- register_t dummy;
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)];
+ char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
};
struct linux_setns_args {
register_t dummy;
@@ -1119,6 +1177,7 @@ struct linux_process_vm_writev_args {
register_t dummy;
};
#define nosys linux_nosys
+int linux_exit(struct thread *, struct linux_exit_args *);
int linux_fork(struct thread *, struct linux_fork_args *);
int linux_open(struct thread *, struct linux_open_args *);
int linux_waitpid(struct thread *, struct linux_waitpid_args *);
@@ -1230,10 +1289,13 @@ int linux_msync(struct thread *, struct linux_msync_args *);
int linux_getsid(struct thread *, struct linux_getsid_args *);
int linux_fdatasync(struct thread *, struct linux_fdatasync_args *);
int linux_sysctl(struct thread *, struct linux_sysctl_args *);
+int linux_sched_setparam(struct thread *, struct linux_sched_setparam_args *);
+int linux_sched_getparam(struct thread *, struct linux_sched_getparam_args *);
int linux_sched_setscheduler(struct thread *, struct linux_sched_setscheduler_args *);
int linux_sched_getscheduler(struct thread *, struct linux_sched_getscheduler_args *);
int linux_sched_get_priority_max(struct thread *, struct linux_sched_get_priority_max_args *);
int linux_sched_get_priority_min(struct thread *, struct linux_sched_get_priority_min_args *);
+int linux_sched_rr_get_interval(struct thread *, struct linux_sched_rr_get_interval_args *);
int linux_nanosleep(struct thread *, struct linux_nanosleep_args *);
int linux_mremap(struct thread *, struct linux_mremap_args *);
int linux_setresuid16(struct thread *, struct linux_setresuid16_args *);
@@ -1422,6 +1484,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#endif /* COMPAT_FREEBSD7 */
+#define LINUX_SYS_AUE_linux_exit AUE_EXIT
#define LINUX_SYS_AUE_linux_fork AUE_FORK
#define LINUX_SYS_AUE_linux_open AUE_OPEN_RWTC
#define LINUX_SYS_AUE_linux_waitpid AUE_WAIT4
@@ -1533,10 +1596,13 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_getsid AUE_GETSID
#define LINUX_SYS_AUE_linux_fdatasync AUE_NULL
#define LINUX_SYS_AUE_linux_sysctl AUE_SYSCTL
+#define LINUX_SYS_AUE_linux_sched_setparam AUE_SCHED_SETPARAM
+#define LINUX_SYS_AUE_linux_sched_getparam AUE_SCHED_GETPARAM
#define LINUX_SYS_AUE_linux_sched_setscheduler AUE_SCHED_SETSCHEDULER
#define LINUX_SYS_AUE_linux_sched_getscheduler AUE_SCHED_GETSCHEDULER
#define LINUX_SYS_AUE_linux_sched_get_priority_max AUE_SCHED_GET_PRIORITY_MAX
#define LINUX_SYS_AUE_linux_sched_get_priority_min AUE_SCHED_GET_PRIORITY_MIN
+#define LINUX_SYS_AUE_linux_sched_rr_get_interval AUE_SCHED_RR_GET_INTERVAL
#define LINUX_SYS_AUE_linux_nanosleep AUE_NULL
#define LINUX_SYS_AUE_linux_mremap AUE_NULL
#define LINUX_SYS_AUE_linux_setresuid16 AUE_SETRESUID
@@ -1633,7 +1699,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_mq_notify AUE_NULL
#define LINUX_SYS_AUE_linux_mq_getsetattr AUE_NULL
#define LINUX_SYS_AUE_linux_kexec_load AUE_NULL
-#define LINUX_SYS_AUE_linux_waitid AUE_NULL
+#define LINUX_SYS_AUE_linux_waitid AUE_WAIT6
#define LINUX_SYS_AUE_linux_add_key AUE_NULL
#define LINUX_SYS_AUE_linux_request_key AUE_NULL
#define LINUX_SYS_AUE_linux_keyctl AUE_NULL
@@ -1656,8 +1722,8 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_readlinkat AUE_READLINKAT
#define LINUX_SYS_AUE_linux_fchmodat AUE_FCHMODAT
#define LINUX_SYS_AUE_linux_faccessat AUE_FACCESSAT
-#define LINUX_SYS_AUE_linux_pselect6 AUE_NULL
-#define LINUX_SYS_AUE_linux_ppoll AUE_NULL
+#define LINUX_SYS_AUE_linux_pselect6 AUE_SELECT
+#define LINUX_SYS_AUE_linux_ppoll AUE_POLL
#define LINUX_SYS_AUE_linux_unshare AUE_NULL
#define LINUX_SYS_AUE_linux_set_robust_list AUE_NULL
#define LINUX_SYS_AUE_linux_get_robust_list AUE_NULL
@@ -1668,7 +1734,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_move_pages AUE_NULL
#define LINUX_SYS_AUE_linux_getcpu AUE_NULL
#define LINUX_SYS_AUE_linux_epoll_pwait AUE_NULL
-#define LINUX_SYS_AUE_linux_utimensat AUE_NULL
+#define LINUX_SYS_AUE_linux_utimensat AUE_FUTIMESAT
#define LINUX_SYS_AUE_linux_signalfd AUE_NULL
#define LINUX_SYS_AUE_linux_timerfd_create AUE_NULL
#define LINUX_SYS_AUE_linux_eventfd AUE_NULL
@@ -1692,7 +1758,7 @@ int linux_process_vm_writev(struct thread *, struct linux_process_vm_writev_args
#define LINUX_SYS_AUE_linux_name_to_handle_at AUE_NULL
#define LINUX_SYS_AUE_linux_open_by_handle_at AUE_NULL
#define LINUX_SYS_AUE_linux_clock_adjtime AUE_NULL
-#define LINUX_SYS_AUE_linux_syncfs AUE_NULL
+#define LINUX_SYS_AUE_linux_syncfs AUE_SYNC
#define LINUX_SYS_AUE_linux_sendmmsg AUE_NULL
#define LINUX_SYS_AUE_linux_setns AUE_NULL
#define LINUX_SYS_AUE_linux_process_vm_readv AUE_NULL
diff --git a/sys/i386/linux/linux_ptrace.c b/sys/i386/linux/linux_ptrace.c
index 46a1169d7025..2925e6bc0107 100644
--- a/sys/i386/linux/linux_ptrace.c
+++ b/sys/i386/linux/linux_ptrace.c
@@ -91,8 +91,7 @@ static __inline int
map_signum(int signum)
{
- if (signum > 0 && signum <= LINUX_SIGTBLSZ)
- signum = linux_to_bsd_signal[_SIG_IDX(signum)];
+ signum = linux_to_bsd_signal(signum);
return ((signum == SIGSTOP)? 0 : signum);
}
diff --git a/sys/i386/linux/linux_syscall.h b/sys/i386/linux/linux_syscall.h
index 178e97c56c13..60c284a656b8 100644
--- a/sys/i386/linux/linux_syscall.h
+++ b/sys/i386/linux/linux_syscall.h
@@ -3,10 +3,10 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/i386/linux/syscalls.master 276509 2015-01-01 18:41:34Z dchagin
+ * created from FreeBSD: head/sys/i386/linux/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
*/
-#define LINUX_SYS_exit 1
+#define LINUX_SYS_linux_exit 1
#define LINUX_SYS_linux_fork 2
#define LINUX_SYS_read 3
#define LINUX_SYS_write 4
@@ -148,14 +148,14 @@
#define LINUX_SYS_munlock 151
#define LINUX_SYS_mlockall 152
#define LINUX_SYS_munlockall 153
-#define LINUX_SYS_sched_setparam 154
-#define LINUX_SYS_sched_getparam 155
+#define LINUX_SYS_linux_sched_setparam 154
+#define LINUX_SYS_linux_sched_getparam 155
#define LINUX_SYS_linux_sched_setscheduler 156
#define LINUX_SYS_linux_sched_getscheduler 157
#define LINUX_SYS_sched_yield 158
#define LINUX_SYS_linux_sched_get_priority_max 159
#define LINUX_SYS_linux_sched_get_priority_min 160
-#define LINUX_SYS_sched_rr_get_interval 161
+#define LINUX_SYS_linux_sched_rr_get_interval 161
#define LINUX_SYS_linux_nanosleep 162
#define LINUX_SYS_linux_mremap 163
#define LINUX_SYS_linux_setresuid16 164
@@ -328,4 +328,4 @@
#define LINUX_SYS_linux_setns 346
#define LINUX_SYS_linux_process_vm_readv 347
#define LINUX_SYS_linux_process_vm_writev 348
-#define LINUX_SYS_MAXSYSCALL 349
+#define LINUX_SYS_MAXSYSCALL 350
diff --git a/sys/i386/linux/linux_syscalls.c b/sys/i386/linux/linux_syscalls.c
index ea05c03b5bf9..64556a9b6cd7 100644
--- a/sys/i386/linux/linux_syscalls.c
+++ b/sys/i386/linux/linux_syscalls.c
@@ -3,13 +3,13 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/i386/linux/syscalls.master 276509 2015-01-01 18:41:34Z dchagin
+ * created from FreeBSD: head/sys/i386/linux/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
*/
const char *linux_syscallnames[] = {
#define nosys linux_nosys
"#0", /* 0 = setup */
- "exit", /* 1 = exit */
+ "linux_exit", /* 1 = linux_exit */
"linux_fork", /* 2 = linux_fork */
"read", /* 3 = read */
"write", /* 4 = write */
@@ -162,14 +162,14 @@ const char *linux_syscallnames[] = {
"munlock", /* 151 = munlock */
"mlockall", /* 152 = mlockall */
"munlockall", /* 153 = munlockall */
- "sched_setparam", /* 154 = sched_setparam */
- "sched_getparam", /* 155 = sched_getparam */
+ "linux_sched_setparam", /* 154 = linux_sched_setparam */
+ "linux_sched_getparam", /* 155 = linux_sched_getparam */
"linux_sched_setscheduler", /* 156 = linux_sched_setscheduler */
"linux_sched_getscheduler", /* 157 = linux_sched_getscheduler */
"sched_yield", /* 158 = sched_yield */
"linux_sched_get_priority_max", /* 159 = linux_sched_get_priority_max */
"linux_sched_get_priority_min", /* 160 = linux_sched_get_priority_min */
- "sched_rr_get_interval", /* 161 = sched_rr_get_interval */
+ "linux_sched_rr_get_interval", /* 161 = linux_sched_rr_get_interval */
"linux_nanosleep", /* 162 = linux_nanosleep */
"linux_mremap", /* 163 = linux_mremap */
"linux_setresuid16", /* 164 = linux_setresuid16 */
@@ -357,4 +357,5 @@ const char *linux_syscallnames[] = {
"linux_setns", /* 346 = linux_setns */
"linux_process_vm_readv", /* 347 = linux_process_vm_readv */
"linux_process_vm_writev", /* 348 = linux_process_vm_writev */
+ "#349", /* 349 = nosys */
};
diff --git a/sys/i386/linux/linux_sysent.c b/sys/i386/linux/linux_sysent.c
index 5e42a0d4252b..922ddbb19aed 100644
--- a/sys/i386/linux/linux_sysent.c
+++ b/sys/i386/linux/linux_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/i386/linux/syscalls.master 276509 2015-01-01 18:41:34Z dchagin
+ * created from FreeBSD: head/sys/i386/linux/syscalls.master 283492 2015-05-24 18:08:01Z dchagin
*/
#include <sys/param.h>
@@ -19,7 +19,7 @@
struct sysent linux_sysent[] = {
#define nosys linux_nosys
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 0 = setup */
- { AS(sys_exit_args), (sy_call_t *)sys_sys_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = exit */
+ { AS(linux_exit_args), (sy_call_t *)linux_exit, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 1 = linux_exit */
{ 0, (sy_call_t *)linux_fork, AUE_FORK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 2 = linux_fork */
{ AS(read_args), (sy_call_t *)sys_read, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 3 = read */
{ AS(write_args), (sy_call_t *)sys_write, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 4 = write */
@@ -172,14 +172,14 @@ struct sysent linux_sysent[] = {
{ AS(munlock_args), (sy_call_t *)sys_munlock, AUE_MUNLOCK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 151 = munlock */
{ AS(mlockall_args), (sy_call_t *)sys_mlockall, AUE_MLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 152 = mlockall */
{ 0, (sy_call_t *)sys_munlockall, AUE_MUNLOCKALL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 153 = munlockall */
- { AS(sched_setparam_args), (sy_call_t *)sys_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 154 = sched_setparam */
- { AS(sched_getparam_args), (sy_call_t *)sys_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = sched_getparam */
+ { AS(linux_sched_setparam_args), (sy_call_t *)linux_sched_setparam, AUE_SCHED_SETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 154 = linux_sched_setparam */
+ { AS(linux_sched_getparam_args), (sy_call_t *)linux_sched_getparam, AUE_SCHED_GETPARAM, NULL, 0, 0, 0, SY_THR_STATIC }, /* 155 = linux_sched_getparam */
{ AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler, AUE_SCHED_SETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 156 = linux_sched_setscheduler */
{ AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler, AUE_SCHED_GETSCHEDULER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 157 = linux_sched_getscheduler */
{ 0, (sy_call_t *)sys_sched_yield, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 158 = sched_yield */
{ AS(linux_sched_get_priority_max_args), (sy_call_t *)linux_sched_get_priority_max, AUE_SCHED_GET_PRIORITY_MAX, NULL, 0, 0, 0, SY_THR_STATIC }, /* 159 = linux_sched_get_priority_max */
{ AS(linux_sched_get_priority_min_args), (sy_call_t *)linux_sched_get_priority_min, AUE_SCHED_GET_PRIORITY_MIN, NULL, 0, 0, 0, SY_THR_STATIC }, /* 160 = linux_sched_get_priority_min */
- { AS(sched_rr_get_interval_args), (sy_call_t *)sys_sched_rr_get_interval, AUE_SCHED_RR_GET_INTERVAL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 161 = sched_rr_get_interval */
+ { AS(linux_sched_rr_get_interval_args), (sy_call_t *)linux_sched_rr_get_interval, AUE_SCHED_RR_GET_INTERVAL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 161 = linux_sched_rr_get_interval */
{ AS(linux_nanosleep_args), (sy_call_t *)linux_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 162 = linux_nanosleep */
{ AS(linux_mremap_args), (sy_call_t *)linux_mremap, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 163 = linux_mremap */
{ AS(linux_setresuid16_args), (sy_call_t *)linux_setresuid16, AUE_SETRESUID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 164 = linux_setresuid16 */
@@ -196,7 +196,7 @@ struct sysent linux_sysent[] = {
{ AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 175 = linux_rt_sigprocmask */
{ AS(linux_rt_sigpending_args), (sy_call_t *)linux_rt_sigpending, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 176 = linux_rt_sigpending */
{ AS(linux_rt_sigtimedwait_args), (sy_call_t *)linux_rt_sigtimedwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 177 = linux_rt_sigtimedwait */
- { 0, (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_rt_sigqueueinfo */
+ { AS(linux_rt_sigqueueinfo_args), (sy_call_t *)linux_rt_sigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 178 = linux_rt_sigqueueinfo */
{ AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 179 = linux_rt_sigsuspend */
{ AS(linux_pread_args), (sy_call_t *)linux_pread, AUE_PREAD, NULL, 0, 0, 0, SY_THR_STATIC }, /* 180 = linux_pread */
{ AS(linux_pwrite_args), (sy_call_t *)linux_pwrite, AUE_PWRITE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 181 = linux_pwrite */
@@ -272,9 +272,9 @@ struct sysent linux_sysent[] = {
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 251 = */
{ AS(linux_exit_group_args), (sy_call_t *)linux_exit_group, AUE_EXIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 252 = linux_exit_group */
{ 0, (sy_call_t *)linux_lookup_dcookie, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 253 = linux_lookup_dcookie */
- { 0, (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_epoll_create */
- { 0, (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_epoll_ctl */
- { 0, (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_epoll_wait */
+ { AS(linux_epoll_create_args), (sy_call_t *)linux_epoll_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 254 = linux_epoll_create */
+ { AS(linux_epoll_ctl_args), (sy_call_t *)linux_epoll_ctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 255 = linux_epoll_ctl */
+ { AS(linux_epoll_wait_args), (sy_call_t *)linux_epoll_wait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 256 = linux_epoll_wait */
{ 0, (sy_call_t *)linux_remap_file_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 257 = linux_remap_file_pages */
{ AS(linux_set_tid_address_args), (sy_call_t *)linux_set_tid_address, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 258 = linux_set_tid_address */
{ AS(linux_timer_create_args), (sy_call_t *)linux_timer_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 259 = linux_timer_create */
@@ -302,7 +302,7 @@ struct sysent linux_sysent[] = {
{ AS(linux_mq_notify_args), (sy_call_t *)linux_mq_notify, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 281 = linux_mq_notify */
{ AS(linux_mq_getsetattr_args), (sy_call_t *)linux_mq_getsetattr, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 282 = linux_mq_getsetattr */
{ 0, (sy_call_t *)linux_kexec_load, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 283 = linux_kexec_load */
- { 0, (sy_call_t *)linux_waitid, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_waitid */
+ { AS(linux_waitid_args), (sy_call_t *)linux_waitid, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 284 = linux_waitid */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 285 = */
{ 0, (sy_call_t *)linux_add_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 286 = linux_add_key */
{ 0, (sy_call_t *)linux_request_key, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 287 = linux_request_key */
@@ -326,8 +326,8 @@ struct sysent linux_sysent[] = {
{ AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_READLINKAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 305 = linux_readlinkat */
{ AS(linux_fchmodat_args), (sy_call_t *)linux_fchmodat, AUE_FCHMODAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 306 = linux_fchmodat */
{ AS(linux_faccessat_args), (sy_call_t *)linux_faccessat, AUE_FACCESSAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 307 = linux_faccessat */
- { 0, (sy_call_t *)linux_pselect6, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_pselect6 */
- { 0, (sy_call_t *)linux_ppoll, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_ppoll */
+ { AS(linux_pselect6_args), (sy_call_t *)linux_pselect6, AUE_SELECT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 308 = linux_pselect6 */
+ { AS(linux_ppoll_args), (sy_call_t *)linux_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 309 = linux_ppoll */
{ 0, (sy_call_t *)linux_unshare, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 310 = linux_unshare */
{ AS(linux_set_robust_list_args), (sy_call_t *)linux_set_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 311 = linux_set_robust_list */
{ AS(linux_get_robust_list_args), (sy_call_t *)linux_get_robust_list, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 312 = linux_get_robust_list */
@@ -337,34 +337,35 @@ struct sysent linux_sysent[] = {
{ 0, (sy_call_t *)linux_vmsplice, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 316 = linux_vmsplice */
{ 0, (sy_call_t *)linux_move_pages, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 317 = linux_move_pages */
{ 0, (sy_call_t *)linux_getcpu, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 318 = linux_getcpu */
- { 0, (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 319 = linux_epoll_pwait */
- { 0, (sy_call_t *)linux_utimensat, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 320 = linux_utimensat */
+ { AS(linux_epoll_pwait_args), (sy_call_t *)linux_epoll_pwait, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 319 = linux_epoll_pwait */
+ { AS(linux_utimensat_args), (sy_call_t *)linux_utimensat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 320 = linux_utimensat */
{ 0, (sy_call_t *)linux_signalfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 321 = linux_signalfd */
{ 0, (sy_call_t *)linux_timerfd_create, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 322 = linux_timerfd_create */
- { 0, (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 323 = linux_eventfd */
- { 0, (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 324 = linux_fallocate */
+ { AS(linux_eventfd_args), (sy_call_t *)linux_eventfd, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 323 = linux_eventfd */
+ { AS(linux_fallocate_args), (sy_call_t *)linux_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 324 = linux_fallocate */
{ 0, (sy_call_t *)linux_timerfd_settime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 325 = linux_timerfd_settime */
{ 0, (sy_call_t *)linux_timerfd_gettime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 326 = linux_timerfd_gettime */
{ 0, (sy_call_t *)linux_signalfd4, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 327 = linux_signalfd4 */
- { 0, (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */
- { 0, (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */
- { 0, (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */
+ { AS(linux_eventfd2_args), (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */
+ { AS(linux_epoll_create1_args), (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */
+ { AS(linux_dup3_args), (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */
{ AS(linux_pipe2_args), (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 331 = linux_pipe2 */
{ 0, (sy_call_t *)linux_inotify_init1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 332 = linux_inotify_init1 */
{ 0, (sy_call_t *)linux_preadv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 333 = linux_preadv */
{ 0, (sy_call_t *)linux_pwritev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 334 = linux_pwritev */
{ 0, (sy_call_t *)linux_rt_tsigqueueinfo, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 335 = linux_rt_tsigqueueinfo */
{ 0, (sy_call_t *)linux_perf_event_open, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 336 = linux_perf_event_open */
- { 0, (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = linux_recvmmsg */
+ { AS(linux_recvmmsg_args), (sy_call_t *)linux_recvmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 337 = linux_recvmmsg */
{ 0, (sy_call_t *)linux_fanotify_init, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 338 = linux_fanotify_init */
{ 0, (sy_call_t *)linux_fanotify_mark, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 339 = linux_fanotify_mark */
- { 0, (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 340 = linux_prlimit64 */
+ { AS(linux_prlimit64_args), (sy_call_t *)linux_prlimit64, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 340 = linux_prlimit64 */
{ 0, (sy_call_t *)linux_name_to_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 341 = linux_name_to_handle_at */
{ 0, (sy_call_t *)linux_open_by_handle_at, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 342 = linux_open_by_handle_at */
{ 0, (sy_call_t *)linux_clock_adjtime, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 343 = linux_clock_adjtime */
- { 0, (sy_call_t *)linux_syncfs, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 344 = linux_syncfs */
- { 0, (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 345 = linux_sendmmsg */
+ { AS(linux_syncfs_args), (sy_call_t *)linux_syncfs, AUE_SYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 344 = linux_syncfs */
+ { AS(linux_sendmmsg_args), (sy_call_t *)linux_sendmmsg, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 345 = linux_sendmmsg */
{ 0, (sy_call_t *)linux_setns, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 346 = linux_setns */
{ 0, (sy_call_t *)linux_process_vm_readv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 347 = linux_process_vm_readv */
{ 0, (sy_call_t *)linux_process_vm_writev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 348 = linux_process_vm_writev */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 349 = nosys */
};
diff --git a/sys/i386/linux/linux_systrace_args.c b/sys/i386/linux/linux_systrace_args.c
index 3564fda7e7c6..85fc9caca4eb 100644
--- a/sys/i386/linux/linux_systrace_args.c
+++ b/sys/i386/linux/linux_systrace_args.c
@@ -12,9 +12,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
int64_t *iarg = (int64_t *) uarg;
switch (sysnum) {
#define nosys linux_nosys
- /* sys_exit */
+ /* linux_exit */
case 1: {
- struct sys_exit_args *p = params;
+ struct linux_exit_args *p = params;
iarg[0] = p->rval; /* int */
*n_args = 1;
break;
@@ -792,7 +792,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
iarg[0] = p->pid; /* l_pid_t */
uarg[1] = (intptr_t) p->status; /* l_int * */
iarg[2] = p->options; /* l_int */
- uarg[3] = (intptr_t) p->rusage; /* struct l_rusage * */
+ uarg[3] = (intptr_t) p->rusage; /* void * */
*n_args = 4;
break;
}
@@ -1081,19 +1081,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 0;
break;
}
- /* sched_setparam */
+ /* linux_sched_setparam */
case 154: {
- struct sched_setparam_args *p = params;
- iarg[0] = p->pid; /* pid_t */
- uarg[1] = (intptr_t) p->param; /* const struct sched_param * */
+ struct linux_sched_setparam_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */
*n_args = 2;
break;
}
- /* sched_getparam */
+ /* linux_sched_getparam */
case 155: {
- struct sched_getparam_args *p = params;
- iarg[0] = p->pid; /* pid_t */
- uarg[1] = (intptr_t) p->param; /* struct sched_param * */
+ struct linux_sched_getparam_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ uarg[1] = (intptr_t) p->param; /* struct l_sched_param * */
*n_args = 2;
break;
}
@@ -1132,9 +1132,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 1;
break;
}
- /* sched_rr_get_interval */
+ /* linux_sched_rr_get_interval */
case 161: {
- struct sched_rr_get_interval_args *p = params;
+ struct linux_sched_rr_get_interval_args *p = params;
iarg[0] = p->pid; /* l_pid_t */
uarg[1] = (intptr_t) p->interval; /* struct l_timespec * */
*n_args = 2;
@@ -1277,7 +1277,11 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_rt_sigqueueinfo */
case 178: {
- *n_args = 0;
+ struct linux_rt_sigqueueinfo_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->sig; /* l_int */
+ uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */
+ *n_args = 3;
break;
}
/* linux_rt_sigsuspend */
@@ -1743,17 +1747,29 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_epoll_create */
case 254: {
- *n_args = 0;
+ struct linux_epoll_create_args *p = params;
+ iarg[0] = p->size; /* l_int */
+ *n_args = 1;
break;
}
/* linux_epoll_ctl */
case 255: {
- *n_args = 0;
+ struct linux_epoll_ctl_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ iarg[1] = p->op; /* l_int */
+ iarg[2] = p->fd; /* l_int */
+ uarg[3] = (intptr_t) p->event; /* struct epoll_event * */
+ *n_args = 4;
break;
}
/* linux_epoll_wait */
case 256: {
- *n_args = 0;
+ struct linux_epoll_wait_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ uarg[1] = (intptr_t) p->events; /* struct epoll_event * */
+ iarg[2] = p->maxevents; /* l_int */
+ iarg[3] = p->timeout; /* l_int */
+ *n_args = 4;
break;
}
/* linux_remap_file_pages */
@@ -1962,7 +1978,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_waitid */
case 284: {
- *n_args = 0;
+ struct linux_waitid_args *p = params;
+ iarg[0] = p->idtype; /* int */
+ iarg[1] = p->id; /* l_pid_t */
+ uarg[2] = (intptr_t) p->info; /* l_siginfo_t * */
+ iarg[3] = p->options; /* int */
+ uarg[4] = (intptr_t) p->rusage; /* void * */
+ *n_args = 5;
break;
}
/* linux_add_key */
@@ -2133,18 +2155,30 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
iarg[0] = p->dfd; /* l_int */
uarg[1] = (intptr_t) p->filename; /* const char * */
iarg[2] = p->amode; /* l_int */
- iarg[3] = p->flag; /* l_int */
- *n_args = 4;
+ *n_args = 3;
break;
}
/* linux_pselect6 */
case 308: {
- *n_args = 0;
+ struct linux_pselect6_args *p = params;
+ iarg[0] = p->nfds; /* l_int */
+ uarg[1] = (intptr_t) p->readfds; /* l_fd_set * */
+ uarg[2] = (intptr_t) p->writefds; /* l_fd_set * */
+ uarg[3] = (intptr_t) p->exceptfds; /* l_fd_set * */
+ uarg[4] = (intptr_t) p->tsp; /* struct l_timespec * */
+ uarg[5] = (intptr_t) p->sig; /* l_uintptr_t * */
+ *n_args = 6;
break;
}
/* linux_ppoll */
case 309: {
- *n_args = 0;
+ struct linux_ppoll_args *p = params;
+ uarg[0] = (intptr_t) p->fds; /* struct pollfd * */
+ uarg[1] = p->nfds; /* uint32_t */
+ uarg[2] = (intptr_t) p->tsp; /* struct l_timespec * */
+ uarg[3] = (intptr_t) p->sset; /* l_sigset_t * */
+ iarg[4] = p->ssize; /* l_size_t */
+ *n_args = 5;
break;
}
/* linux_unshare */
@@ -2201,12 +2235,23 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_epoll_pwait */
case 319: {
- *n_args = 0;
+ struct linux_epoll_pwait_args *p = params;
+ iarg[0] = p->epfd; /* l_int */
+ uarg[1] = (intptr_t) p->events; /* struct epoll_event * */
+ iarg[2] = p->maxevents; /* l_int */
+ iarg[3] = p->timeout; /* l_int */
+ uarg[4] = (intptr_t) p->mask; /* l_sigset_t * */
+ *n_args = 5;
break;
}
/* linux_utimensat */
case 320: {
- *n_args = 0;
+ struct linux_utimensat_args *p = params;
+ iarg[0] = p->dfd; /* l_int */
+ uarg[1] = (intptr_t) p->pathname; /* const char * */
+ uarg[2] = (intptr_t) p->times; /* const struct l_timespec * */
+ iarg[3] = p->flags; /* l_int */
+ *n_args = 4;
break;
}
/* linux_signalfd */
@@ -2221,12 +2266,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_eventfd */
case 323: {
- *n_args = 0;
+ struct linux_eventfd_args *p = params;
+ iarg[0] = p->initval; /* l_uint */
+ *n_args = 1;
break;
}
/* linux_fallocate */
case 324: {
- *n_args = 0;
+ struct linux_fallocate_args *p = params;
+ iarg[0] = p->fd; /* l_int */
+ iarg[1] = p->mode; /* l_int */
+ iarg[2] = p->offset; /* l_loff_t */
+ iarg[3] = p->len; /* l_loff_t */
+ *n_args = 4;
break;
}
/* linux_timerfd_settime */
@@ -2246,17 +2298,26 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_eventfd2 */
case 328: {
- *n_args = 0;
+ struct linux_eventfd2_args *p = params;
+ iarg[0] = p->initval; /* l_uint */
+ iarg[1] = p->flags; /* l_int */
+ *n_args = 2;
break;
}
/* linux_epoll_create1 */
case 329: {
- *n_args = 0;
+ struct linux_epoll_create1_args *p = params;
+ iarg[0] = p->flags; /* l_int */
+ *n_args = 1;
break;
}
/* linux_dup3 */
case 330: {
- *n_args = 0;
+ struct linux_dup3_args *p = params;
+ iarg[0] = p->oldfd; /* l_int */
+ iarg[1] = p->newfd; /* l_int */
+ iarg[2] = p->flags; /* l_int */
+ *n_args = 3;
break;
}
/* linux_pipe2 */
@@ -2294,7 +2355,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_recvmmsg */
case 337: {
- *n_args = 0;
+ struct linux_recvmmsg_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */
+ iarg[2] = p->vlen; /* l_uint */
+ iarg[3] = p->flags; /* l_uint */
+ uarg[4] = (intptr_t) p->timeout; /* struct l_timespec * */
+ *n_args = 5;
break;
}
/* linux_fanotify_init */
@@ -2309,7 +2376,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_prlimit64 */
case 340: {
- *n_args = 0;
+ struct linux_prlimit64_args *p = params;
+ iarg[0] = p->pid; /* l_pid_t */
+ iarg[1] = p->resource; /* l_uint */
+ uarg[2] = (intptr_t) p->new; /* struct rlimit * */
+ uarg[3] = (intptr_t) p->old; /* struct rlimit * */
+ *n_args = 4;
break;
}
/* linux_name_to_handle_at */
@@ -2329,12 +2401,19 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_syncfs */
case 344: {
- *n_args = 0;
+ struct linux_syncfs_args *p = params;
+ iarg[0] = p->fd; /* l_int */
+ *n_args = 1;
break;
}
/* linux_sendmmsg */
case 345: {
- *n_args = 0;
+ struct linux_sendmmsg_args *p = params;
+ iarg[0] = p->s; /* l_int */
+ uarg[1] = (intptr_t) p->msg; /* struct l_mmsghdr * */
+ iarg[2] = p->vlen; /* l_uint */
+ iarg[3] = p->flags; /* l_uint */
+ *n_args = 4;
break;
}
/* linux_setns */
@@ -2363,7 +2442,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
const char *p = NULL;
switch (sysnum) {
#define nosys linux_nosys
- /* sys_exit */
+ /* linux_exit */
case 1:
switch(ndx) {
case 0:
@@ -3548,7 +3627,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
p = "l_int";
break;
case 3:
- p = "struct l_rusage *";
+ p = "void *";
break;
default:
break;
@@ -3982,27 +4061,27 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
/* munlockall */
case 153:
break;
- /* sched_setparam */
+ /* linux_sched_setparam */
case 154:
switch(ndx) {
case 0:
- p = "pid_t";
+ p = "l_pid_t";
break;
case 1:
- p = "const struct sched_param *";
+ p = "struct l_sched_param *";
break;
default:
break;
};
break;
- /* sched_getparam */
+ /* linux_sched_getparam */
case 155:
switch(ndx) {
case 0:
- p = "pid_t";
+ p = "l_pid_t";
break;
case 1:
- p = "struct sched_param *";
+ p = "struct l_sched_param *";
break;
default:
break;
@@ -4057,7 +4136,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
- /* sched_rr_get_interval */
+ /* linux_sched_rr_get_interval */
case 161:
switch(ndx) {
case 0:
@@ -4298,6 +4377,19 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_rt_sigqueueinfo */
case 178:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_siginfo_t *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_rt_sigsuspend */
case 179:
@@ -4970,12 +5062,51 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_epoll_create */
case 254:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_epoll_ctl */
case 255:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "struct epoll_event *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_epoll_wait */
case 256:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct epoll_event *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_remap_file_pages */
case 257:
@@ -5299,6 +5430,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_waitid */
case 284:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "l_pid_t";
+ break;
+ case 2:
+ p = "l_siginfo_t *";
+ break;
+ case 3:
+ p = "int";
+ break;
+ case 4:
+ p = "void *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_add_key */
case 286:
@@ -5558,18 +5708,56 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 2:
p = "l_int";
break;
- case 3:
- p = "l_int";
- break;
default:
break;
};
break;
/* linux_pselect6 */
case 308:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_fd_set *";
+ break;
+ case 2:
+ p = "l_fd_set *";
+ break;
+ case 3:
+ p = "l_fd_set *";
+ break;
+ case 4:
+ p = "struct l_timespec *";
+ break;
+ case 5:
+ p = "l_uintptr_t *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_ppoll */
case 309:
+ switch(ndx) {
+ case 0:
+ p = "struct pollfd *";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "struct l_timespec *";
+ break;
+ case 3:
+ p = "l_sigset_t *";
+ break;
+ case 4:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_unshare */
case 310:
@@ -5623,9 +5811,44 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_epoll_pwait */
case 319:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct epoll_event *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ case 4:
+ p = "l_sigset_t *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_utimensat */
case 320:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "const char *";
+ break;
+ case 2:
+ p = "const struct l_timespec *";
+ break;
+ case 3:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_signalfd */
case 321:
@@ -5635,9 +5858,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_eventfd */
case 323:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
break;
/* linux_fallocate */
case 324:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_loff_t";
+ break;
+ case 3:
+ p = "l_loff_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_timerfd_settime */
case 325:
@@ -5650,12 +5896,42 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_eventfd2 */
case 328:
+ switch(ndx) {
+ case 0:
+ p = "l_uint";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_epoll_create1 */
case 329:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_dup3 */
case 330:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_pipe2 */
case 331:
@@ -5687,6 +5963,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_recvmmsg */
case 337:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_mmsghdr *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ case 3:
+ p = "l_uint";
+ break;
+ case 4:
+ p = "struct l_timespec *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_fanotify_init */
case 338:
@@ -5696,6 +5991,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_prlimit64 */
case 340:
+ switch(ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "l_uint";
+ break;
+ case 2:
+ p = "struct rlimit *";
+ break;
+ case 3:
+ p = "struct rlimit *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_name_to_handle_at */
case 341:
@@ -5708,9 +6019,32 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_syncfs */
case 344:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ default:
+ break;
+ };
break;
/* linux_sendmmsg */
case 345:
+ switch(ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "struct l_mmsghdr *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ case 3:
+ p = "l_uint";
+ break;
+ default:
+ break;
+ };
break;
/* linux_setns */
case 346:
@@ -5733,7 +6067,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
const char *p = NULL;
switch (sysnum) {
#define nosys linux_nosys
- /* sys_exit */
+ /* linux_exit */
case 1:
if (ndx == 0 || ndx == 1)
p = "void";
@@ -6365,12 +6699,12 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* munlockall */
case 153:
- /* sched_setparam */
+ /* linux_sched_setparam */
case 154:
if (ndx == 0 || ndx == 1)
p = "int";
break;
- /* sched_getparam */
+ /* linux_sched_getparam */
case 155:
if (ndx == 0 || ndx == 1)
p = "int";
@@ -6397,7 +6731,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
- /* sched_rr_get_interval */
+ /* linux_sched_rr_get_interval */
case 161:
if (ndx == 0 || ndx == 1)
p = "int";
@@ -6475,6 +6809,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_rt_sigqueueinfo */
case 178:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_rt_sigsuspend */
case 179:
if (ndx == 0 || ndx == 1)
@@ -6729,10 +7066,19 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 253:
/* linux_epoll_create */
case 254:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_epoll_ctl */
case 255:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_epoll_wait */
case 256:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_remap_file_pages */
case 257:
/* linux_set_tid_address */
@@ -6847,6 +7193,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 283:
/* linux_waitid */
case 284:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_add_key */
case 286:
/* linux_request_key */
@@ -6932,8 +7281,14 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_pselect6 */
case 308:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_ppoll */
case 309:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_unshare */
case 310:
/* linux_set_robust_list */
@@ -6960,16 +7315,28 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 318:
/* linux_epoll_pwait */
case 319:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_utimensat */
case 320:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_signalfd */
case 321:
/* linux_timerfd_create */
case 322:
/* linux_eventfd */
case 323:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_fallocate */
case 324:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_timerfd_settime */
case 325:
/* linux_timerfd_gettime */
@@ -6978,10 +7345,19 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 327:
/* linux_eventfd2 */
case 328:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_epoll_create1 */
case 329:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_dup3 */
case 330:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_pipe2 */
case 331:
if (ndx == 0 || ndx == 1)
@@ -6999,12 +7375,18 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 336:
/* linux_recvmmsg */
case 337:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_fanotify_init */
case 338:
/* linux_fanotify_mark */
case 339:
/* linux_prlimit64 */
case 340:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_name_to_handle_at */
case 341:
/* linux_open_by_handle_at */
@@ -7013,8 +7395,14 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 343:
/* linux_syncfs */
case 344:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_sendmmsg */
case 345:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_setns */
case 346:
/* linux_process_vm_readv */
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 67d5056d7398..acf23acd7b48 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/syscallsubr.h>
+#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/vnode.h>
@@ -71,17 +72,23 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_misc.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.h>
+#include <compat/linux/linux_vdso.h>
MODULE_VERSION(linux, 1);
-MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
-
#if BYTE_ORDER == LITTLE_ENDIAN
#define SHELLMAGIC 0x2123 /* #! */
#else
#define SHELLMAGIC 0x2321
#endif
+#if defined(DEBUG)
+SYSCTL_PROC(_compat_linux, OID_AUTO, debug,
+ CTLTYPE_STRING | CTLFLAG_RW,
+ 0, 0, linux_sysctl_debug, "A",
+ "Linux debugging control");
+#endif
+
/*
* Allow the sendsig functions to use the ldebug() facility
* even though they are not syscalls themselves. Map them
@@ -93,13 +100,15 @@ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
#define LINUX_PS_STRINGS (LINUX_USRSTACK - sizeof(struct ps_strings))
-extern char linux_sigcode[];
-extern int linux_szsigcode;
+static int linux_szsigcode;
+static vm_object_t linux_shared_page_obj;
+static char *linux_shared_page_mapping;
+extern char _binary_linux_locore_o_start;
+extern char _binary_linux_locore_o_end;
extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
-SET_DECLARE(linux_device_handler_set, struct linux_device_handler);
static int linux_fixup(register_t **stack_base,
struct image_params *iparams);
@@ -110,12 +119,15 @@ static void exec_linux_setregs(struct thread *td,
struct image_params *imgp, u_long stack);
static register_t *linux_copyout_strings(struct image_params *imgp);
static boolean_t linux_trans_osrel(const Elf_Note *note, int32_t *osrel);
+static void linux_vdso_install(void *param);
+static void linux_vdso_deinstall(void *param);
static int linux_szplatform;
-const char *linux_platform;
+const char *linux_kplatform;
static eventhandler_tag linux_exit_tag;
static eventhandler_tag linux_exec_tag;
+static eventhandler_tag linux_thread_dtor_tag;
/*
* Linux syscalls return negative errno's, we do positive and map them
@@ -137,28 +149,6 @@ static int bsd_to_linux_errno[ELAST + 1] = {
-72, -67, -71
};
-int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
- LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
- LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
- LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS,
- LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
- LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
- LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
- LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
- 0, LINUX_SIGUSR1, LINUX_SIGUSR2
-};
-
-int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
- SIGHUP, SIGINT, SIGQUIT, SIGILL,
- SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
- SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
- SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
- SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
- SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
- SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
- SIGIO, SIGURG, SIGSYS
-};
-
#define LINUX_T_UNKNOWN 255
static int _bsd_to_linux_trapcode[] = {
LINUX_T_UNKNOWN, /* 0 */
@@ -198,6 +188,10 @@ static int _bsd_to_linux_trapcode[] = {
_bsd_to_linux_trapcode[(code)]: \
LINUX_T_UNKNOWN)
+LINUX_VDSO_SYM_INTPTR(linux_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux_rt_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux_vsyscall);
+
/*
* If FreeBSD & Linux have a difference of opinion about what a trap
* means, deal with it here.
@@ -208,15 +202,15 @@ static int
translate_traps(int signal, int trap_code)
{
if (signal != SIGBUS)
- return signal;
+ return (signal);
switch (trap_code) {
case T_PROTFLT:
case T_TSSFLT:
case T_DOUBLEFLT:
case T_PAGEFLT:
- return SIGSEGV;
+ return (SIGSEGV);
default:
- return signal;
+ return (signal);
}
}
@@ -254,6 +248,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
args = (Elf32_Auxargs *)imgp->auxargs;
pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
+ AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO_EHDR,
+ imgp->proc->p_sysent->sv_shared_page_base);
+ AUXARGS_ENTRY(pos, LINUX_AT_SYSINFO, linux_vsyscall);
AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);
/*
@@ -279,6 +276,9 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
AUXARGS_ENTRY(pos, LINUX_AT_PLATFORM, PTROUT(uplatform));
+ AUXARGS_ENTRY(pos, LINUX_AT_RANDOM, imgp->canary);
+ if (imgp->execpathp != 0)
+ AUXARGS_ENTRY(pos, LINUX_AT_EXECFN, imgp->execpathp);
if (args->execfd != -1)
AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
AUXARGS_ENTRY(pos, AT_NULL, 0);
@@ -302,23 +302,45 @@ linux_copyout_strings(struct image_params *imgp)
char *stringp, *destp;
register_t *stack_base;
struct ps_strings *arginfo;
+ char canary[LINUX_AT_RANDOM_LEN];
+ size_t execpath_len;
struct proc *p;
/*
* Calculate string base and vector table pointers.
- * Also deal with signal trampoline code for this exec type.
*/
p = imgp->proc;
+ if (imgp->execpath != NULL && imgp->auxargs != NULL)
+ execpath_len = strlen(imgp->execpath) + 1;
+ else
+ execpath_len = 0;
arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform -
+ roundup(sizeof(canary), sizeof(char *)) -
+ roundup(execpath_len, sizeof(char *)) -
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
/*
* install LINUX_PLATFORM
*/
- copyout(linux_platform, ((caddr_t)arginfo - linux_szplatform),
+ copyout(linux_kplatform, ((caddr_t)arginfo - linux_szplatform),
linux_szplatform);
+ if (execpath_len != 0) {
+ imgp->execpathp = (uintptr_t)arginfo -
+ linux_szplatform - execpath_len;
+ copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len);
+ }
+
+ /*
+ * Prepare the canary for SSP.
+ */
+ arc4rand(canary, sizeof(canary), 0);
+ imgp->canary = (uintptr_t)arginfo - linux_szplatform -
+ roundup(execpath_len, sizeof(char *)) -
+ roundup(sizeof(canary), sizeof(char *));
+ copyout(canary, (void *)imgp->canary, sizeof(canary));
+
/*
* If we have a valid auxargs ptr, prepare some room
* on the stack.
@@ -398,10 +420,6 @@ linux_copyout_strings(struct image_params *imgp)
return (stack_base);
}
-
-
-extern unsigned long linux_sznonrtsigcode;
-
static void
linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
@@ -440,9 +458,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/*
* Build the argument list for the signal handler.
*/
- if (p->p_sysent->sv_sigtbl)
- if (sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
+ sig = bsd_to_linux_signal(sig);
bzero(&frame, sizeof(frame));
@@ -468,7 +484,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
- frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0];
+ frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__mask;
frame.sf_sc.uc_mcontext.sc_gs = rgs();
frame.sf_sc.uc_mcontext.sc_fs = regs->tf_fs;
frame.sf_sc.uc_mcontext.sc_es = regs->tf_es;
@@ -477,6 +493,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
frame.sf_sc.uc_mcontext.sc_esi = regs->tf_esi;
frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_ebp;
frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_ebx;
+ frame.sf_sc.uc_mcontext.sc_esp = regs->tf_esp;
frame.sf_sc.uc_mcontext.sc_edx = regs->tf_edx;
frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_ecx;
frame.sf_sc.uc_mcontext.sc_eax = regs->tf_eax;
@@ -514,7 +531,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
* Build context to run handler in.
*/
regs->tf_esp = (int)fp;
- regs->tf_eip = p->p_sysent->sv_sigcode_base + linux_sznonrtsigcode;
+ regs->tf_eip = linux_rt_sigcode;
regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
@@ -546,7 +563,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
struct l_sigframe *fp, frame;
l_sigset_t lmask;
int sig, code;
- int oonstack, i;
+ int oonstack;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
@@ -582,9 +599,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/*
* Build the argument list for the signal handler.
*/
- if (p->p_sysent->sv_sigtbl)
- if (sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
+ sig = bsd_to_linux_signal(sig);
bzero(&frame, sizeof(frame));
@@ -596,7 +611,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/*
* Build the signal context to be used by sigreturn.
*/
- frame.sf_sc.sc_mask = lmask.__bits[0];
+ frame.sf_sc.sc_mask = lmask.__mask;
frame.sf_sc.sc_gs = rgs();
frame.sf_sc.sc_fs = regs->tf_fs;
frame.sf_sc.sc_es = regs->tf_es;
@@ -605,6 +620,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
frame.sf_sc.sc_esi = regs->tf_esi;
frame.sf_sc.sc_ebp = regs->tf_ebp;
frame.sf_sc.sc_ebx = regs->tf_ebx;
+ frame.sf_sc.sc_esp = regs->tf_esp;
frame.sf_sc.sc_edx = regs->tf_edx;
frame.sf_sc.sc_ecx = regs->tf_ecx;
frame.sf_sc.sc_eax = regs->tf_eax;
@@ -617,8 +633,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
frame.sf_sc.sc_cr2 = (register_t)ksi->ksi_addr;
frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(ksi->ksi_trapno);
- for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
- frame.sf_extramask[i] = lmask.__bits[i+1];
+ frame.sf_extramask[0] = lmask.__mask;
if (copyout(&frame, fp, sizeof(frame)) != 0) {
/*
@@ -633,7 +648,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
* Build context to run handler in.
*/
regs->tf_esp = (int)fp;
- regs->tf_eip = p->p_sysent->sv_sigcode_base;
+ regs->tf_eip = linux_sigcode;
regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
@@ -661,7 +676,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
struct trapframe *regs;
l_sigset_t lmask;
sigset_t bmask;
- int eflags, i;
+ int eflags;
ksiginfo_t ksi;
regs = td->td_frame;
@@ -684,7 +699,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
eflags = frame.sf_sc.sc_eflags;
if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
- return(EINVAL);
+ return (EINVAL);
/*
* Don't allow users to load a valid privileged %cs. Let the
@@ -699,12 +714,10 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
ksi.ksi_trapno = T_PROTFLT;
ksi.ksi_addr = (void *)regs->tf_eip;
trapsignal(td, &ksi);
- return(EINVAL);
+ return (EINVAL);
}
- lmask.__bits[0] = frame.sf_sc.sc_mask;
- for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
- lmask.__bits[i+1] = frame.sf_extramask[i];
+ lmask.__mask = frame.sf_sc.sc_mask;
linux_to_bsd_sigset(&lmask, &bmask);
kern_sigprocmask(td, SIG_SETMASK, &bmask, NULL, 0);
@@ -775,7 +788,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
eflags = context->sc_eflags;
if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
- return(EINVAL);
+ return (EINVAL);
/*
* Don't allow users to load a valid privileged %cs. Let the
@@ -790,7 +803,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
ksi.ksi_trapno = T_PROTFLT;
ksi.ksi_addr = (void *)regs->tf_eip;
trapsignal(td, &ksi);
- return(EINVAL);
+ return (EINVAL);
}
linux_to_bsd_sigset(&uc.uc_sigmask, &bmask);
@@ -852,7 +865,8 @@ linux_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
sa->args[5] = frame->tf_ebp; /* Unconfirmed */
if (sa->code >= p->p_sysent->sv_size)
- sa->callp = &p->p_sysent->sv_table[0];
+ /* nosys */
+ sa->callp = &p->p_sysent->sv_table[LINUX_SYS_MAXSYSCALL];
else
sa->callp = &p->p_sysent->sv_table[sa->code];
sa->narg = sa->callp->sy_narg;
@@ -942,14 +956,14 @@ struct sysentvec linux_sysvec = {
.sv_size = LINUX_SYS_MAXSYSCALL,
.sv_table = linux_sysent,
.sv_mask = 0,
- .sv_sigsize = LINUX_SIGTBLSZ,
- .sv_sigtbl = bsd_to_linux_signal,
+ .sv_sigsize = 0,
+ .sv_sigtbl = NULL,
.sv_errsize = ELAST + 1,
.sv_errtbl = bsd_to_linux_errno,
.sv_transtrap = translate_traps,
.sv_fixup = linux_fixup,
.sv_sendsig = linux_sendsig,
- .sv_sigcode = linux_sigcode,
+ .sv_sigcode = &_binary_linux_locore_o_start,
.sv_szsigcode = &linux_szsigcode,
.sv_prepsyscall = NULL,
.sv_name = "Linux a.out",
@@ -973,6 +987,7 @@ struct sysentvec linux_sysvec = {
.sv_shared_page_base = LINUX_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
+ .sv_thread_detach = linux_thread_detach,
};
INIT_SYSENTVEC(aout_sysvec, &linux_sysvec);
@@ -980,14 +995,14 @@ struct sysentvec elf_linux_sysvec = {
.sv_size = LINUX_SYS_MAXSYSCALL,
.sv_table = linux_sysent,
.sv_mask = 0,
- .sv_sigsize = LINUX_SIGTBLSZ,
- .sv_sigtbl = bsd_to_linux_signal,
+ .sv_sigsize = 0,
+ .sv_sigtbl = NULL,
.sv_errsize = ELAST + 1,
.sv_errtbl = bsd_to_linux_errno,
.sv_transtrap = translate_traps,
.sv_fixup = elf_linux_fixup,
.sv_sendsig = linux_sendsig,
- .sv_sigcode = linux_sigcode,
+ .sv_sigcode = &_binary_linux_locore_o_start,
.sv_szsigcode = &linux_szsigcode,
.sv_prepsyscall = NULL,
.sv_name = "Linux ELF",
@@ -1011,8 +1026,41 @@ struct sysentvec elf_linux_sysvec = {
.sv_shared_page_base = LINUX_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = linux_schedtail,
+ .sv_thread_detach = linux_thread_detach,
+};
+
+static void
+linux_vdso_install(void *param)
+{
+
+ linux_szsigcode = (&_binary_linux_locore_o_end -
+ &_binary_linux_locore_o_start);
+
+ if (linux_szsigcode > elf_linux_sysvec.sv_shared_page_len)
+ panic("Linux invalid vdso size\n");
+
+ __elfN(linux_vdso_fixup)(&elf_linux_sysvec);
+
+ linux_shared_page_obj = __elfN(linux_shared_page_init)
+ (&linux_shared_page_mapping);
+
+ __elfN(linux_vdso_reloc)(&elf_linux_sysvec, LINUX_SHAREDPAGE);
+
+ bcopy(elf_linux_sysvec.sv_sigcode, linux_shared_page_mapping,
+ linux_szsigcode);
+ elf_linux_sysvec.sv_shared_page_obj = linux_shared_page_obj;
+}
+SYSINIT(elf_linux_vdso_init, SI_SUB_EXEC, SI_ORDER_ANY,
+ (sysinit_cfunc_t)linux_vdso_install, NULL);
+
+static void
+linux_vdso_deinstall(void *param)
+{
+
+ __elfN(linux_shared_page_fini)(linux_shared_page_obj);
};
-INIT_SYSENTVEC(elf_sysvec, &elf_linux_sysvec);
+SYSUNINIT(elf_linux_vdso_uninit, SI_SUB_EXEC, SI_ORDER_FIRST,
+ (sysinit_cfunc_t)linux_vdso_deinstall, NULL);
static char GNU_ABI_VENDOR[] = "GNU";
static int GNULINUX_ABI_DESC = 0;
@@ -1084,7 +1132,6 @@ linux_elf_modevent(module_t mod, int type, void *data)
Elf32_Brandinfo **brandinfo;
int error;
struct linux_ioctl_handler **lihp;
- struct linux_device_handler **ldhp;
error = 0;
@@ -1097,18 +1144,16 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (error == 0) {
SET_FOREACH(lihp, linux_ioctl_handler_set)
linux_ioctl_register_handler(*lihp);
- SET_FOREACH(ldhp, linux_device_handler_set)
- linux_device_register_handler(*ldhp);
- mtx_init(&emul_lock, "emuldata lock", NULL, MTX_DEF);
- sx_init(&emul_shared_lock, "emuldata->shared lock");
LIST_INIT(&futex_list);
mtx_init(&futex_mtx, "ftllk", NULL, MTX_DEF);
linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit,
NULL, 1000);
linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec,
NULL, 1000);
- linux_get_machine(&linux_platform);
- linux_szplatform = roundup(strlen(linux_platform) + 1,
+ linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor,
+ linux_thread_dtor, NULL, EVENTHANDLER_PRI_ANY);
+ linux_get_machine(&linux_kplatform);
+ linux_szplatform = roundup(strlen(linux_kplatform) + 1,
sizeof(char *));
linux_osd_jail_register();
stclohz = (stathz ? stathz : hz);
@@ -1131,13 +1176,10 @@ linux_elf_modevent(module_t mod, int type, void *data)
if (error == 0) {
SET_FOREACH(lihp, linux_ioctl_handler_set)
linux_ioctl_unregister_handler(*lihp);
- SET_FOREACH(ldhp, linux_device_handler_set)
- linux_device_unregister_handler(*ldhp);
- mtx_destroy(&emul_lock);
- sx_destroy(&emul_shared_lock);
mtx_destroy(&futex_mtx);
EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag);
EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag);
+ EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag);
linux_osd_jail_deregister();
if (bootverbose)
printf("Linux ELF exec handler removed\n");
@@ -1145,9 +1187,9 @@ linux_elf_modevent(module_t mod, int type, void *data)
printf("Could not deinstall ELF interpreter entry\n");
break;
default:
- return EOPNOTSUPP;
+ return (EOPNOTSUPP);
}
- return error;
+ return (error);
}
static moduledata_t linux_elf_mod = {
diff --git a/sys/i386/linux/linux_vdso.lds.s b/sys/i386/linux/linux_vdso.lds.s
new file mode 100644
index 000000000000..dcb61cf5e06f
--- /dev/null
+++ b/sys/i386/linux/linux_vdso.lds.s
@@ -0,0 +1,65 @@
+/*
+ * Linker script for 32-bit vDSO.
+ * Copied from Linux kernel arch/x86/vdso/vdso-layout.lds.S
+ * and arch/x86/vdso/vdso32/vdso32.lds.S
+ *
+ * $FreeBSD$
+ */
+
+SECTIONS
+{
+ . = . + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+ .data : {
+ *(.data*)
+ *(.sdata*)
+ *(.got.plt) *(.got)
+ *(.gnu.linkonce.d.*)
+ *(.bss*)
+ *(.dynbss*)
+ *(.gnu.linkonce.b.*)
+ }
+
+ .altinstructions : { *(.altinstructions) }
+ .altinstr_replacement : { *(.altinstr_replacement) }
+
+ . = ALIGN(0x100);
+ .text : { *(.text*) } :text =0x90909090
+}
+
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
+
+ENTRY(linux_vsyscall);
+
+VERSION
+{
+ LINUX_2.5 {
+ global:
+ linux_vsyscall;
+ linux_sigcode;
+ linux_rt_sigcode;
+ local: *;
+ };
+}
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index 5b4f3a6340fe..e6609a9c4b08 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -37,8 +37,7 @@
; #ifdef's, etc. may be included, and are copied to the output files.
0 AUE_NULL UNIMPL setup
-1 AUE_EXIT NOPROTO { void sys_exit(int rval); } exit \
- sys_exit_args void
+1 AUE_EXIT STD { void linux_exit(int rval); }
2 AUE_FORK STD { int linux_fork(void); }
3 AUE_NULL NOPROTO { int read(int fd, char *buf, \
u_int nbyte); }
@@ -209,7 +208,7 @@
113 AUE_NULL STD { int linux_vm86old(void); }
114 AUE_WAIT4 STD { int linux_wait4(l_pid_t pid, \
l_int *status, l_int options, \
- struct l_rusage *rusage); }
+ void *rusage); }
115 AUE_SWAPOFF STD { int linux_swapoff(void); }
116 AUE_NULL STD { int linux_sysinfo(struct l_sysinfo *info); }
117 AUE_NULL STD { int linux_ipc(l_uint what, l_int arg1, \
@@ -270,10 +269,10 @@
151 AUE_MUNLOCK NOPROTO { int munlock(const void *addr, size_t len); }
152 AUE_MLOCKALL NOPROTO { int mlockall(int how); }
153 AUE_MUNLOCKALL NOPROTO { int munlockall(void); }
-154 AUE_SCHED_SETPARAM NOPROTO { int sched_setparam(pid_t pid, \
- const struct sched_param *param); }
-155 AUE_SCHED_GETPARAM NOPROTO { int sched_getparam(pid_t pid, \
- struct sched_param *param); }
+154 AUE_SCHED_SETPARAM STD { int linux_sched_setparam(l_pid_t pid, \
+ struct l_sched_param *param); }
+155 AUE_SCHED_GETPARAM STD { int linux_sched_getparam(l_pid_t pid, \
+ struct l_sched_param *param); }
156 AUE_SCHED_SETSCHEDULER STD { int linux_sched_setscheduler( \
l_pid_t pid, l_int policy, \
struct l_sched_param *param); }
@@ -284,8 +283,8 @@
l_int policy); }
160 AUE_SCHED_GET_PRIORITY_MIN STD { int linux_sched_get_priority_min( \
l_int policy); }
-161 AUE_SCHED_RR_GET_INTERVAL NOPROTO { int sched_rr_get_interval(l_pid_t pid, \
- struct l_timespec *interval); }
+161 AUE_SCHED_RR_GET_INTERVAL STD { int linux_sched_rr_get_interval( \
+ l_pid_t pid, struct l_timespec *interval); }
162 AUE_NULL STD { int linux_nanosleep( \
const struct l_timespec *rqtp, \
struct l_timespec *rmtp); }
@@ -321,7 +320,8 @@
l_siginfo_t *ptr, \
struct l_timeval *timeout, \
l_size_t sigsetsize); }
-178 AUE_NULL STD { int linux_rt_sigqueueinfo(void); }
+178 AUE_NULL STD { int linux_rt_sigqueueinfo(l_pid_t pid, l_int sig, \
+ l_siginfo_t *info); }
179 AUE_NULL STD { int linux_rt_sigsuspend( \
l_sigset_t *newset, \
l_size_t sigsetsize); }
@@ -432,9 +432,11 @@
251 AUE_NULL UNIMPL
252 AUE_EXIT STD { int linux_exit_group(int error_code); }
253 AUE_NULL STD { int linux_lookup_dcookie(void); }
-254 AUE_NULL STD { int linux_epoll_create(void); }
-255 AUE_NULL STD { int linux_epoll_ctl(void); }
-256 AUE_NULL STD { int linux_epoll_wait(void); }
+254 AUE_NULL STD { int linux_epoll_create(l_int size); }
+255 AUE_NULL STD { int linux_epoll_ctl(l_int epfd, l_int op, l_int fd, \
+ struct epoll_event *event); }
+256 AUE_NULL STD { int linux_epoll_wait(l_int epfd, struct epoll_event *events, \
+ l_int maxevents, l_int timeout); }
257 AUE_NULL STD { int linux_remap_file_pages(void); }
258 AUE_NULL STD { int linux_set_tid_address(int *tidptr); }
259 AUE_NULL STD { int linux_timer_create(clockid_t clock_id, \
@@ -475,7 +477,9 @@
282 AUE_NULL STD { int linux_mq_getsetattr(l_mqd_t mqd, const struct mq_attr *attr, \
struct mq_attr *oattr); }
283 AUE_NULL STD { int linux_kexec_load(void); }
-284 AUE_NULL STD { int linux_waitid(void); }
+284 AUE_WAIT6 STD { int linux_waitid(int idtype, l_pid_t id, \
+ l_siginfo_t *info, int options, \
+ void *rusage); }
285 AUE_NULL UNIMPL
; linux 2.6.11:
286 AUE_NULL STD { int linux_add_key(void); }
@@ -513,9 +517,13 @@
char *buf, l_int bufsiz); }
306 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \
l_mode_t mode); }
-307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode, l_int flag); }
-308 AUE_NULL STD { int linux_pselect6(void); }
-309 AUE_NULL STD { int linux_ppoll(void); }
+307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, \
+ l_int amode); }
+308 AUE_SELECT STD { int linux_pselect6(l_int nfds, l_fd_set *readfds, \
+ l_fd_set *writefds, l_fd_set *exceptfds, \
+ struct l_timespec *tsp, l_uintptr_t *sig); }
+309 AUE_POLL STD { int linux_ppoll(struct pollfd *fds, uint32_t nfds, \
+ struct l_timespec *tsp, l_sigset_t *sset, l_size_t ssize); }
310 AUE_NULL STD { int linux_unshare(void); }
; linux 2.6.17:
311 AUE_NULL STD { int linux_set_robust_list(struct linux_robust_list_head *head, \
@@ -530,22 +538,26 @@
317 AUE_NULL STD { int linux_move_pages(void); }
; linux 2.6.19:
318 AUE_NULL STD { int linux_getcpu(void); }
-319 AUE_NULL STD { int linux_epoll_pwait(void); }
+319 AUE_NULL STD { int linux_epoll_pwait(l_int epfd, struct epoll_event *events, \
+ l_int maxevents, l_int timeout, l_sigset_t *mask); }
; linux 2.6.22:
-320 AUE_NULL STD { int linux_utimensat(void); }
+320 AUE_FUTIMESAT STD { int linux_utimensat(l_int dfd, const char *pathname, \
+ const struct l_timespec *times, l_int flags); }
321 AUE_NULL STD { int linux_signalfd(void); }
322 AUE_NULL STD { int linux_timerfd_create(void); }
-323 AUE_NULL STD { int linux_eventfd(void); }
+323 AUE_NULL STD { int linux_eventfd(l_uint initval); }
; linux 2.6.23:
-324 AUE_NULL STD { int linux_fallocate(void); }
+324 AUE_NULL STD { int linux_fallocate(l_int fd, l_int mode, \
+ l_loff_t offset, l_loff_t len); }
; linux 2.6.25:
325 AUE_NULL STD { int linux_timerfd_settime(void); }
326 AUE_NULL STD { int linux_timerfd_gettime(void); }
; linux 2.6.27:
327 AUE_NULL STD { int linux_signalfd4(void); }
-328 AUE_NULL STD { int linux_eventfd2(void); }
-329 AUE_NULL STD { int linux_epoll_create1(void); }
-330 AUE_NULL STD { int linux_dup3(void); }
+328 AUE_NULL STD { int linux_eventfd2(l_uint initval, l_int flags); }
+329 AUE_NULL STD { int linux_epoll_create1(l_int flags); }
+330 AUE_NULL STD { int linux_dup3(l_int oldfd, \
+ l_int newfd, l_int flags); }
331 AUE_NULL STD { int linux_pipe2(l_int *pipefds, l_int flags); }
332 AUE_NULL STD { int linux_inotify_init1(void); }
; linux 2.6.30:
@@ -555,17 +567,26 @@
335 AUE_NULL STD { int linux_rt_tsigqueueinfo(void); }
336 AUE_NULL STD { int linux_perf_event_open(void); }
; linux 2.6.33:
-337 AUE_NULL STD { int linux_recvmmsg(void); }
+337 AUE_NULL STD { int linux_recvmmsg(l_int s, \
+ struct l_mmsghdr *msg, l_uint vlen, \
+ l_uint flags, struct l_timespec *timeout); }
338 AUE_NULL STD { int linux_fanotify_init(void); }
339 AUE_NULL STD { int linux_fanotify_mark(void); }
; linux 2.6.36:
-340 AUE_NULL STD { int linux_prlimit64(void); }
+340 AUE_NULL STD { int linux_prlimit64(l_pid_t pid, \
+ l_uint resource, \
+ struct rlimit *new, \
+ struct rlimit *old); }
; later:
341 AUE_NULL STD { int linux_name_to_handle_at(void); }
342 AUE_NULL STD { int linux_open_by_handle_at(void); }
343 AUE_NULL STD { int linux_clock_adjtime(void); }
-344 AUE_NULL STD { int linux_syncfs(void); }
-345 AUE_NULL STD { int linux_sendmmsg(void); }
+344 AUE_SYNC STD { int linux_syncfs(l_int fd); }
+345 AUE_NULL STD { int linux_sendmmsg(l_int s, \
+ struct l_mmsghdr *msg, l_uint vlen, \
+ l_uint flags); }
346 AUE_NULL STD { int linux_setns(void); }
347 AUE_NULL STD { int linux_process_vm_readv(void); }
348 AUE_NULL STD { int linux_process_vm_writev(void); }
+; please, keep this line at the end.
+349 AUE_NULL UNIMPL nosys
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c
index 3ae78de42f0c..3165ac05eb0c 100644
--- a/sys/kern/imgact_aout.c
+++ b/sys/kern/imgact_aout.c
@@ -99,6 +99,7 @@ struct sysentvec aout_sysvec = {
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
#elif defined(__amd64__)
@@ -247,7 +248,7 @@ exec_aout_imgact(struct image_params *imgp)
a_out->a_text > maxtsiz ||
/* data + bss can't exceed rlimit */
- a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA) ||
+ a_out->a_data + bss_size > lim_cur_proc(imgp->proc, RLIMIT_DATA) ||
racct_set(imgp->proc, RACCT_DATA, a_out->a_data + bss_size) != 0) {
PROC_UNLOCK(imgp->proc);
return (ENOMEM);
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index a98a15d146d1..067512831e3e 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -732,7 +732,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
u_long addr, baddr, et_dyn_addr, entry = 0, proghdr = 0;
int32_t osrel = 0;
int error = 0, i, n, interp_name_len = 0;
- const char *interp = NULL, *newinterp = NULL;
+ const char *err_str = NULL, *interp = NULL, *newinterp = NULL;
Elf_Brandinfo *brand_info;
char *path;
struct sysentvec *sv;
@@ -755,11 +755,14 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
if ((hdr->e_phoff > PAGE_SIZE) ||
(u_int)hdr->e_phentsize * hdr->e_phnum > PAGE_SIZE - hdr->e_phoff) {
/* Only support headers in first page for now */
+ uprintf("Program headers not in the first page\n");
return (ENOEXEC);
}
- phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
- if (!aligned(phdr, Elf_Addr))
+ phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
+ if (!aligned(phdr, Elf_Addr)) {
+ uprintf("Unaligned program headers\n");
return (ENOEXEC);
+ }
n = 0;
baddr = 0;
for (i = 0; i < hdr->e_phnum; i++) {
@@ -773,8 +776,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
/* Path to interpreter */
if (phdr[i].p_filesz > MAXPATHLEN ||
phdr[i].p_offset > PAGE_SIZE ||
- phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset)
+ phdr[i].p_filesz > PAGE_SIZE - phdr[i].p_offset) {
+ uprintf("Invalid PT_INTERP\n");
return (ENOEXEC);
+ }
interp = imgp->image_header + phdr[i].p_offset;
interp_name_len = phdr[i].p_filesz;
break;
@@ -795,8 +800,10 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
return (ENOEXEC);
}
if (hdr->e_type == ET_DYN) {
- if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0)
+ if ((brand_info->flags & BI_CAN_EXEC_DYN) == 0) {
+ uprintf("Cannot execute shared object\n");
return (ENOEXEC);
+ }
/*
* Honour the base load address from the dso if it is
* non-zero for some reason.
@@ -901,12 +908,19 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
* not actually fault in all the segments pages.
*/
PROC_LOCK(imgp->proc);
- if (data_size > lim_cur(imgp->proc, RLIMIT_DATA) ||
- text_size > maxtsiz ||
- total_size > lim_cur(imgp->proc, RLIMIT_VMEM) ||
- racct_set(imgp->proc, RACCT_DATA, data_size) != 0 ||
- racct_set(imgp->proc, RACCT_VMEM, total_size) != 0) {
+ if (data_size > lim_cur_proc(imgp->proc, RLIMIT_DATA))
+ err_str = "Data segment size exceeds process limit";
+ else if (text_size > maxtsiz)
+ err_str = "Text segment size exceeds system limit";
+ else if (total_size > lim_cur_proc(imgp->proc, RLIMIT_VMEM))
+ err_str = "Total segment size exceeds process limit";
+ else if (racct_set(imgp->proc, RACCT_DATA, data_size) != 0)
+ err_str = "Data segment size exceeds resource limit";
+ else if (racct_set(imgp->proc, RACCT_VMEM, total_size) != 0)
+ err_str = "Total segment size exceeds resource limit";
+ if (err_str != NULL) {
PROC_UNLOCK(imgp->proc);
+ uprintf("%s\n", err_str);
return (ENOMEM);
}
@@ -922,7 +936,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
* calculation is that it leaves room for the heap to grow to
* its maximum allowed size.
*/
- addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(imgp->proc,
+ addr = round_page((vm_offset_t)vmspace->vm_daddr + lim_max(curthread,
RLIMIT_DATA));
PROC_UNLOCK(imgp->proc);
@@ -1969,7 +1983,7 @@ note_procstat_rlimit(void *arg, struct sbuf *sb, size_t *sizep)
sbuf_bcat(sb, &structsize, sizeof(structsize));
PROC_LOCK(p);
for (i = 0; i < RLIM_NLIMITS; i++)
- lim_rlimit(p, i, &rlim[i]);
+ lim_rlimit_proc(p, i, &rlim[i]);
PROC_UNLOCK(p);
sbuf_bcat(sb, rlim, sizeof(rlim));
}
diff --git a/sys/kern/imgact_gzip.c b/sys/kern/imgact_gzip.c
index ab77a885524a..47b728004286 100644
--- a/sys/kern/imgact_gzip.c
+++ b/sys/kern/imgact_gzip.c
@@ -212,7 +212,7 @@ do_aout_hdr(struct imgact_gzip * gz)
/* data + bss can't exceed rlimit */
gz->a_out.a_data + gz->bss_size >
- lim_cur(gz->ip->proc, RLIMIT_DATA) ||
+ lim_cur_proc(gz->ip->proc, RLIMIT_DATA) ||
racct_set(gz->ip->proc, RACCT_DATA,
gz->a_out.a_data + gz->bss_size) != 0) {
PROC_UNLOCK(gz->ip->proc);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index c26335650621..37539c41dc9f 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -411,6 +411,7 @@ struct sysentvec null_sysvec = {
.sv_fetch_syscall_args = null_fetch_syscall_args,
.sv_syscallnames = NULL,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
/*
@@ -522,8 +523,6 @@ proc0_init(void *dummy __unused)
#ifdef MAC
mac_cred_create_swapper(newcred);
#endif
- td->td_ucred = crhold(newcred);
-
/* Create sigacts. */
p->p_sigacts = sigacts_alloc();
@@ -555,6 +554,10 @@ proc0_init(void *dummy __unused)
p->p_limit->pl_rlimit[RLIMIT_MEMLOCK].rlim_max = pageablemem;
p->p_cpulimit = RLIM_INFINITY;
+ PROC_LOCK(p);
+ thread_cow_get_proc(td, p);
+ PROC_UNLOCK(p);
+
/* Initialize resource accounting structures. */
racct_create(&p->p_racct);
@@ -842,10 +845,10 @@ create_init(const void *udata __unused)
audit_cred_proc1(newcred);
#endif
proc_set_cred(initproc, newcred);
+ cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
PROC_UNLOCK(initproc);
sx_xunlock(&proctree_lock);
crfree(oldcred);
- cred_update_thread(FIRST_THREAD_IN_PROC(initproc));
cpu_set_fork_handler(FIRST_THREAD_IN_PROC(initproc), start_init, NULL);
}
SYSINIT(init, SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 78483962eccc..f6f819464f30 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -109,7 +109,7 @@ static void fdgrowtable(struct filedesc *fdp, int nfd);
static void fdgrowtable_exp(struct filedesc *fdp, int nfd);
static void fdunused(struct filedesc *fdp, int fd);
static void fdused(struct filedesc *fdp, int fd);
-static int getmaxfd(struct proc *p);
+static int getmaxfd(struct thread *td);
/* Flags for do_dup() */
#define DUP_FIXED 0x1 /* Force fixed allocation. */
@@ -178,9 +178,6 @@ volatile int openfiles; /* actual number of open files */
struct mtx sigio_lock; /* mtx to protect pointers to sigio */
void (*mq_fdclose)(struct thread *td, int fd, struct file *fp);
-/* A mutex to protect the association between a proc and filedesc. */
-static struct mtx fdesc_mtx;
-
/*
* If low >= size, just return low. Otherwise find the first zero bit in the
* given bitmap, starting at low and not exceeding size - 1. Return size if
@@ -331,16 +328,19 @@ struct getdtablesize_args {
int
sys_getdtablesize(struct thread *td, struct getdtablesize_args *uap)
{
- struct proc *p = td->td_proc;
+#ifdef RACCT
uint64_t lim;
+#endif
- PROC_LOCK(p);
td->td_retval[0] =
- min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
+ min((int)lim_cur(td, RLIMIT_NOFILE), maxfilesperproc);
+#ifdef RACCT
+ PROC_LOCK(td->td_proc);
lim = racct_get_limit(td->td_proc, RACCT_NOFILE);
- PROC_UNLOCK(p);
+ PROC_UNLOCK(td->td_proc);
if (lim < td->td_retval[0])
td->td_retval[0] = lim;
+#endif
return (0);
}
@@ -783,15 +783,10 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
}
static int
-getmaxfd(struct proc *p)
+getmaxfd(struct thread *td)
{
- int maxfd;
-
- PROC_LOCK(p);
- maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
- PROC_UNLOCK(p);
- return (maxfd);
+ return (min((int)lim_cur(td, RLIMIT_NOFILE), maxfilesperproc));
}
/*
@@ -819,7 +814,7 @@ do_dup(struct thread *td, int flags, int old, int new)
return (EBADF);
if (new < 0)
return (flags & DUP_FCNTL ? EINVAL : EBADF);
- maxfd = getmaxfd(p);
+ maxfd = getmaxfd(td);
if (new >= maxfd)
return (flags & DUP_FCNTL ? EINVAL : EBADF);
@@ -1619,7 +1614,7 @@ fdalloc(struct thread *td, int minfd, int *result)
if (fdp->fd_freefile > minfd)
minfd = fdp->fd_freefile;
- maxfd = getmaxfd(p);
+ maxfd = getmaxfd(td);
/*
* Search the bitmap for a free descriptor starting at minfd.
@@ -1809,8 +1804,8 @@ fdinit(struct filedesc *fdp, bool prepfiles)
/* Create the file descriptor table. */
FILEDESC_LOCK_INIT(newfdp);
- newfdp->fd_refcnt = 1;
- newfdp->fd_holdcnt = 1;
+ refcount_init(&newfdp->fd_refcnt, 1);
+ refcount_init(&newfdp->fd_holdcnt, 1);
newfdp->fd_cmask = CMASK;
newfdp->fd_map = newfdp0->fd_dmap;
newfdp->fd_lastfile = -1;
@@ -1852,24 +1847,19 @@ fdhold(struct proc *p)
{
struct filedesc *fdp;
- mtx_lock(&fdesc_mtx);
+ PROC_LOCK_ASSERT(p, MA_OWNED);
fdp = p->p_fd;
if (fdp != NULL)
- fdp->fd_holdcnt++;
- mtx_unlock(&fdesc_mtx);
+ refcount_acquire(&fdp->fd_holdcnt);
return (fdp);
}
static void
fddrop(struct filedesc *fdp)
{
- int i;
if (fdp->fd_holdcnt > 1) {
- mtx_lock(&fdesc_mtx);
- i = --fdp->fd_holdcnt;
- mtx_unlock(&fdesc_mtx);
- if (i > 0)
+ if (refcount_release(&fdp->fd_holdcnt) == 0)
return;
}
@@ -1884,9 +1874,7 @@ struct filedesc *
fdshare(struct filedesc *fdp)
{
- FILEDESC_XLOCK(fdp);
- fdp->fd_refcnt++;
- FILEDESC_XUNLOCK(fdp);
+ refcount_acquire(&fdp->fd_refcnt);
return (fdp);
}
@@ -2032,6 +2020,7 @@ retry:
void
fdescfree(struct thread *td)
{
+ struct proc *p;
struct filedesc0 *fdp0;
struct filedesc *fdp;
struct freetable *ft, *tft;
@@ -2040,31 +2029,29 @@ fdescfree(struct thread *td)
struct vnode *cdir, *jdir, *rdir;
int i;
- fdp = td->td_proc->p_fd;
+ p = td->td_proc;
+ fdp = p->p_fd;
MPASS(fdp != NULL);
#ifdef RACCT
if (racct_enable) {
- PROC_LOCK(td->td_proc);
- racct_set(td->td_proc, RACCT_NOFILE, 0);
- PROC_UNLOCK(td->td_proc);
+ PROC_LOCK(p);
+ racct_set(p, RACCT_NOFILE, 0);
+ PROC_UNLOCK(p);
}
#endif
if (td->td_proc->p_fdtol != NULL)
fdclearlocks(td);
- mtx_lock(&fdesc_mtx);
- td->td_proc->p_fd = NULL;
- mtx_unlock(&fdesc_mtx);
+ PROC_LOCK(p);
+ p->p_fd = NULL;
+ PROC_UNLOCK(p);
- FILEDESC_XLOCK(fdp);
- i = --fdp->fd_refcnt;
- if (i > 0) {
- FILEDESC_XUNLOCK(fdp);
+ if (refcount_release(&fdp->fd_refcnt) == 0)
return;
- }
+ FILEDESC_XLOCK(fdp);
cdir = fdp->fd_cdir;
fdp->fd_cdir = NULL;
rdir = fdp->fd_rdir;
@@ -2884,7 +2871,9 @@ mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
nrele = 0;
sx_slock(&allproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
+ PROC_LOCK(p);
fdp = fdhold(p);
+ PROC_UNLOCK(p);
if (fdp == NULL)
continue;
FILEDESC_XLOCK(fdp);
@@ -2979,9 +2968,13 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
n = 0;
sx_slock(&allproc_lock);
FOREACH_PROC_IN_SYSTEM(p) {
- if (p->p_state == PRS_NEW)
+ PROC_LOCK(p);
+ if (p->p_state == PRS_NEW) {
+ PROC_UNLOCK(p);
continue;
+ }
fdp = fdhold(p);
+ PROC_UNLOCK(p);
if (fdp == NULL)
continue;
/* overestimates sparse tables. */
@@ -3008,8 +3001,8 @@ sysctl_kern_file(SYSCTL_HANDLER_ARGS)
}
xf.xf_pid = p->p_pid;
xf.xf_uid = p->p_ucred->cr_uid;
- PROC_UNLOCK(p);
fdp = fdhold(p);
+ PROC_UNLOCK(p);
if (fdp == NULL)
continue;
FILEDESC_SLOCK(fdp);
@@ -3644,7 +3637,6 @@ filelistinit(void *dummy)
filedesc0_zone = uma_zcreate("filedesc0", sizeof(struct filedesc0),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF);
- mtx_init(&fdesc_mtx, "fdesc", NULL, MTX_DEF);
}
SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL);
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index b6d8a7973022..ff17fe9b8d7c 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -737,6 +737,13 @@ filt_usertouch(struct knote *kn, struct kevent *kev, u_long type)
int
sys_kqueue(struct thread *td, struct kqueue_args *uap)
{
+
+ return (kern_kqueue(td, 0));
+}
+
+int
+kern_kqueue(struct thread *td, int flags)
+{
struct filedesc *fdp;
struct kqueue *kq;
struct file *fp;
@@ -747,17 +754,13 @@ sys_kqueue(struct thread *td, struct kqueue_args *uap)
p = td->td_proc;
cred = td->td_ucred;
crhold(cred);
- PROC_LOCK(p);
- if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td->td_proc,
- RLIMIT_KQUEUES))) {
- PROC_UNLOCK(p);
+ if (!chgkqcnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_KQUEUES))) {
crfree(cred);
return (ENOMEM);
}
- PROC_UNLOCK(p);
fdp = p->p_fd;
- error = falloc(td, &fp, &fd, 0);
+ error = falloc(td, &fp, &fd, flags);
if (error)
goto done2;
@@ -888,12 +891,9 @@ int
kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout)
{
- struct kevent keva[KQ_NEVENTS];
- struct kevent *kevp, *changes;
- struct kqueue *kq;
- struct file *fp;
cap_rights_t rights;
- int i, n, nerrors, error;
+ struct file *fp;
+ int error;
cap_rights_init(&rights);
if (nchanges > 0)
@@ -904,9 +904,24 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
if (error != 0)
return (error);
+ error = kern_kevent_fp(td, fp, nchanges, nevents, k_ops, timeout);
+ fdrop(fp, td);
+
+ return (error);
+}
+
+int
+kern_kevent_fp(struct thread *td, struct file *fp, int nchanges, int nevents,
+ struct kevent_copyops *k_ops, const struct timespec *timeout)
+{
+ struct kevent keva[KQ_NEVENTS];
+ struct kevent *kevp, *changes;
+ struct kqueue *kq;
+ int i, n, nerrors, error;
+
error = kqueue_acquire(fp, &kq);
if (error != 0)
- goto done_norel;
+ return (error);
nerrors = 0;
@@ -946,8 +961,6 @@ kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
error = kqueue_scan(kq, nevents, k_ops, timeout, keva, td);
done:
kqueue_release(kq, 0);
-done_norel:
- fdrop(fp, td);
return (error);
}
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 8668f0d0d030..375e64459c4c 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -966,13 +966,10 @@ exec_map_first_page(imgp)
}
initial_pagein = i;
rv = vm_pager_get_pages(object, ma, initial_pagein, 0);
- ma[0] = vm_page_lookup(object, 0);
- if ((rv != VM_PAGER_OK) || (ma[0] == NULL)) {
- if (ma[0] != NULL) {
- vm_page_lock(ma[0]);
- vm_page_free(ma[0]);
- vm_page_unlock(ma[0]);
- }
+ if (rv != VM_PAGER_OK) {
+ vm_page_lock(ma[0]);
+ vm_page_free(ma[0]);
+ vm_page_unlock(ma[0]);
VM_OBJECT_WUNLOCK(object);
return (EIO);
}
@@ -1073,7 +1070,7 @@ exec_new_vmspace(imgp, sv)
if (imgp->stack_sz != 0) {
ssiz = trunc_page(imgp->stack_sz);
PROC_LOCK(p);
- lim_rlimit(p, RLIMIT_STACK, &rlim_stack);
+ lim_rlimit_proc(p, RLIMIT_STACK, &rlim_stack);
PROC_UNLOCK(p);
if (ssiz > rlim_stack.rlim_max)
ssiz = rlim_stack.rlim_max;
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index e760bc81db16..9ce6d343c1f4 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -205,6 +205,12 @@ exit1(struct thread *td, int rv)
}
/*
+ * Deref SU mp, since the thread does not return to userspace.
+ */
+ if (softdep_ast_cleanup != NULL)
+ softdep_ast_cleanup();
+
+ /*
* MUST abort all other threads before proceeding past here.
*/
PROC_LOCK(p);
@@ -525,6 +531,8 @@ exit1(struct thread *td, int rv)
*/
while ((q = LIST_FIRST(&p->p_orphans)) != NULL) {
PROC_LOCK(q);
+ CTR2(KTR_PTRACE, "exit: pid %d, clearing orphan %d", p->p_pid,
+ q->p_pid);
clear_orphan(q);
PROC_UNLOCK(q);
}
@@ -857,6 +865,9 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
t = proc_realparent(p);
PROC_LOCK(t);
PROC_LOCK(p);
+ CTR2(KTR_PTRACE,
+ "wait: traced child %d moved back to parent %d", p->p_pid,
+ t->p_pid);
proc_reparent(p, t);
p->p_oppid = 0;
PROC_UNLOCK(p);
@@ -950,14 +961,13 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
static int
proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id,
- int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo)
+ int *status, int options, struct __wrusage *wrusage, siginfo_t *siginfo,
+ int check_only)
{
- struct proc *q;
struct rusage *rup;
sx_assert(&proctree_lock, SA_XLOCKED);
- q = td->td_proc;
PROC_LOCK(p);
switch (idtype) {
@@ -1088,7 +1098,7 @@ proc_to_reap(struct thread *td, struct proc *p, idtype_t idtype, id_t id,
calccru(p, &rup->ru_utime, &rup->ru_stime);
}
- if (p->p_state == PRS_ZOMBIE) {
+ if (p->p_state == PRS_ZOMBIE && !check_only) {
PROC_SLOCK(p);
proc_reap(td, p, status, options);
return (-1);
@@ -1182,7 +1192,7 @@ loop:
sx_xlock(&proctree_lock);
LIST_FOREACH(p, &q->p_children, p_sibling) {
ret = proc_to_reap(td, p, idtype, id, status, options,
- wrusage, siginfo);
+ wrusage, siginfo, 0);
if (ret == 0)
continue;
else if (ret == 1)
@@ -1216,6 +1226,10 @@ loop:
PROC_UNLOCK(q);
}
+ CTR4(KTR_PTRACE,
+ "wait: returning trapped pid %d status %#x (xstat %d) xthread %d",
+ p->p_pid, W_STOPCODE(p->p_xstat), p->p_xstat,
+ p->p_xthread != NULL ? p->p_xthread->td_tid : -1);
PROC_UNLOCK(p);
return (0);
}
@@ -1280,15 +1294,17 @@ loop:
* for. By maintaining a list of orphans we allow the parent
* to successfully wait until the child becomes a zombie.
*/
- LIST_FOREACH(p, &q->p_orphans, p_orphan) {
- ret = proc_to_reap(td, p, idtype, id, status, options,
- wrusage, siginfo);
- if (ret == 0)
- continue;
- else if (ret == 1)
- nfound++;
- else
- return (0);
+ if (nfound == 0) {
+ LIST_FOREACH(p, &q->p_orphans, p_orphan) {
+ ret = proc_to_reap(td, p, idtype, id, NULL, options,
+ NULL, NULL, 1);
+ if (ret != 0) {
+ KASSERT(ret != -1, ("reaped an orphan (pid %d)",
+ (int)td->td_retval[0]));
+ nfound++;
+ break;
+ }
+ }
}
if (nfound == 0) {
sx_xunlock(&proctree_lock);
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 2c7fe2e1764a..3fd4f09b9912 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -496,7 +496,6 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
p2->p_swtick = ticks;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
- td2->td_ucred = crhold(p2->p_ucred);
if (flags & RFSIGSHARE) {
p2->p_sigacts = sigacts_hold(p1->p_sigacts);
@@ -526,6 +525,8 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
*/
lim_fork(p1, p2);
+ thread_cow_get_proc(td2, p2);
+
pstats_fork(p1->p_stats, p2->p_stats);
PROC_UNLOCK(p1);
@@ -911,10 +912,8 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp,
if (error == 0)
ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, 0);
else {
- PROC_LOCK(p1);
ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1,
- lim_cur(p1, RLIMIT_NPROC));
- PROC_UNLOCK(p1);
+ lim_cur(td, RLIMIT_NPROC));
}
if (ok) {
do_fork(td, flags, newproc, td2, vm2, pdflags);
@@ -1035,6 +1034,9 @@ fork_return(struct thread *td, struct trapframe *frame)
dbg = p->p_pptr->p_pptr;
p->p_flag |= P_TRACED;
p->p_oppid = p->p_pptr->p_pid;
+ CTR2(KTR_PTRACE,
+ "fork_return: attaching to new child pid %d: oppid %d",
+ p->p_pid, p->p_oppid);
proc_reparent(p, dbg);
sx_xunlock(&proctree_lock);
td->td_dbgflags |= TDB_CHILD;
diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c
index ee94de0e78a5..863bbc626ff3 100644
--- a/sys/kern/kern_kthread.c
+++ b/sys/kern/kern_kthread.c
@@ -289,7 +289,7 @@ kthread_add(void (*func)(void *), void *arg, struct proc *p,
cpu_set_fork_handler(newtd, func, arg);
newtd->td_pflags |= TDP_KTHREAD;
- newtd->td_ucred = crhold(p->p_ucred);
+ thread_cow_get_proc(newtd, p);
/* this code almost the same as create_thread() in kern_thr.c */
p->p_flag |= P_HADTHREADS;
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
index ea6f7a62a69c..72fc4348ff1d 100644
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -384,6 +384,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
@@ -414,6 +415,9 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
CTR4(KTR_LOCK,
"_mtx_lock_sleep: %s contested (lock=%p) at %s:%d",
m->lock_object.lo_name, (void *)m->mtx_lock, file, line);
+#ifdef KDTRACE_HOOKS
+ all_time -= lockstat_nsecs();
+#endif
while (!_mtx_obtain_lock(m, tid)) {
#ifdef KDTRACE_HOOKS
@@ -517,6 +521,9 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
sleep_cnt++;
#endif
}
+#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
+#endif
#ifdef KTR
if (cont_logged) {
CTR4(KTR_CONTENTION,
@@ -534,7 +541,7 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t tid, int opts,
* Only record the loops spinning and not sleeping.
*/
if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_MTX_LOCK_SPIN, m, (spin_cnt - sleep_cnt));
+ LOCKSTAT_RECORD1(LS_MTX_LOCK_SPIN, m, (all_time - sleep_time));
#endif
}
@@ -574,6 +581,9 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
int contested = 0;
uint64_t waittime = 0;
#endif
+#ifdef KDTRACE_HOOKS
+ int64_t spin_time = 0;
+#endif
if (SCHEDULER_STOPPED())
return;
@@ -589,6 +599,9 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
PMC_SOFT_CALL( , , lock, failed);
#endif
lock_profile_obtain_lock_failed(&m->lock_object, &contested, &waittime);
+#ifdef KDTRACE_HOOKS
+ spin_time -= lockstat_nsecs();
+#endif
while (!_mtx_obtain_lock(m, tid)) {
/* Give interrupts a chance while we spin. */
@@ -606,6 +619,9 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
}
spinlock_enter();
}
+#ifdef KDTRACE_HOOKS
+ spin_time += lockstat_nsecs();
+#endif
if (LOCK_LOG_TEST(&m->lock_object, opts))
CTR1(KTR_LOCK, "_mtx_lock_spin: %p spin done", m);
@@ -614,7 +630,7 @@ _mtx_lock_spin_cookie(volatile uintptr_t *c, uintptr_t tid, int opts,
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_SPIN_LOCK_ACQUIRE, m,
contested, waittime, (file), (line));
- LOCKSTAT_RECORD1(LS_MTX_SPIN_LOCK_SPIN, m, i);
+ LOCKSTAT_RECORD1(LS_MTX_SPIN_LOCK_SPIN, m, spin_time);
}
#endif /* SMP */
@@ -629,7 +645,7 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
uint64_t waittime = 0;
#endif
#ifdef KDTRACE_HOOKS
- uint64_t spin_cnt = 0;
+ int64_t spin_time = 0;
#endif
i = 0;
@@ -638,6 +654,9 @@ thread_lock_flags_(struct thread *td, int opts, const char *file, int line)
if (SCHEDULER_STOPPED())
return;
+#ifdef KDTRACE_HOOKS
+ spin_time -= lockstat_nsecs();
+#endif
for (;;) {
retry:
spinlock_enter();
@@ -654,9 +673,6 @@ retry:
WITNESS_CHECKORDER(&m->lock_object,
opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line, NULL);
while (!_mtx_obtain_lock(m, tid)) {
-#ifdef KDTRACE_HOOKS
- spin_cnt++;
-#endif
if (m->mtx_lock == tid) {
m->mtx_recurse++;
break;
@@ -685,17 +701,17 @@ retry:
if (m == td->td_lock)
break;
__mtx_unlock_spin(m); /* does spinlock_exit() */
+ }
#ifdef KDTRACE_HOOKS
- spin_cnt++;
+ spin_time += lockstat_nsecs();
#endif
- }
if (m->mtx_recurse == 0)
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_MTX_SPIN_LOCK_ACQUIRE,
m, contested, waittime, (file), (line));
LOCK_LOG_LOCK("LOCK", &m->lock_object, opts, m->mtx_recurse, file,
line);
WITNESS_LOCK(&m->lock_object, opts | LOP_EXCLUSIVE, file, line);
- LOCKSTAT_RECORD1(LS_THREAD_LOCK_SPIN, m, spin_cnt);
+ LOCKSTAT_RECORD1(LS_THREAD_LOCK_SPIN, m, spin_time);
}
struct mtx *
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 6618c0849373..27c6f407d5a5 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -2113,7 +2113,15 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS)
vref(vp);
break;
case OBJT_SWAP:
- kve->kve_type = KVME_TYPE_SWAP;
+ if ((lobj->flags & OBJ_TMPFS_NODE) != 0) {
+ kve->kve_type = KVME_TYPE_VNODE;
+ if ((lobj->flags & OBJ_TMPFS) != 0) {
+ vp = lobj->un_pager.swp.swp_tmpfs;
+ vref(vp);
+ }
+ } else {
+ kve->kve_type = KVME_TYPE_SWAP;
+ }
break;
case OBJT_DEVICE:
kve->kve_type = KVME_TYPE_DEVICE;
@@ -2339,7 +2347,15 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb)
vref(vp);
break;
case OBJT_SWAP:
- kve->kve_type = KVME_TYPE_SWAP;
+ if ((lobj->flags & OBJ_TMPFS_NODE) != 0) {
+ kve->kve_type = KVME_TYPE_VNODE;
+ if ((lobj->flags & OBJ_TMPFS) != 0) {
+ vp = lobj->un_pager.swp.swp_tmpfs;
+ vref(vp);
+ }
+ } else {
+ kve->kve_type = KVME_TYPE_SWAP;
+ }
break;
case OBJT_DEVICE:
kve->kve_type = KVME_TYPE_DEVICE;
@@ -2599,7 +2615,7 @@ sysctl_kern_proc_rlimit(SYSCTL_HANDLER_ARGS)
*/
if (req->oldptr != NULL) {
PROC_LOCK(p);
- lim_rlimit(p, which, &rlim);
+ lim_rlimit_proc(p, which, &rlim);
PROC_UNLOCK(p);
}
error = SYSCTL_OUT(req, &rlim, sizeof(rlim));
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 9c49f716f73e..b531763b8b14 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1946,9 +1946,8 @@ cred_update_thread(struct thread *td)
p = td->td_proc;
cred = td->td_ucred;
- PROC_LOCK(p);
+ PROC_LOCK_ASSERT(p, MA_OWNED);
td->td_ucred = crhold(p->p_ucred);
- PROC_UNLOCK(p);
if (cred != NULL)
crfree(cred);
}
@@ -1987,6 +1986,8 @@ proc_set_cred(struct proc *p, struct ucred *newcred)
oldcred = p->p_ucred;
p->p_ucred = newcred;
+ if (newcred != NULL)
+ PROC_UPDATE_COW(p);
return (oldcred);
}
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index dac49cd5fe3b..546f3b298022 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -560,15 +560,11 @@ ogetrlimit(struct thread *td, register struct ogetrlimit_args *uap)
{
struct orlimit olim;
struct rlimit rl;
- struct proc *p;
int error;
if (uap->which >= RLIM_NLIMITS)
return (EINVAL);
- p = td->td_proc;
- PROC_LOCK(p);
- lim_rlimit(p, uap->which, &rl);
- PROC_UNLOCK(p);
+ lim_rlimit(td, uap->which, &rl);
/*
* XXX would be more correct to convert only RLIM_INFINITY to the
@@ -625,7 +621,7 @@ lim_cb(void *arg)
}
PROC_STATUNLOCK(p);
if (p->p_rux.rux_runtime > p->p_cpulimit * cpu_tickrate()) {
- lim_rlimit(p, RLIMIT_CPU, &rlim);
+ lim_rlimit_proc(p, RLIMIT_CPU, &rlim);
if (p->p_rux.rux_runtime >= rlim.rlim_max * cpu_tickrate()) {
killproc(p, "exceeded maximum CPU limit");
} else {
@@ -667,29 +663,21 @@ kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
limp->rlim_max = RLIM_INFINITY;
oldssiz.rlim_cur = 0;
- newlim = NULL;
+ newlim = lim_alloc();
PROC_LOCK(p);
- if (lim_shared(p->p_limit)) {
- PROC_UNLOCK(p);
- newlim = lim_alloc();
- PROC_LOCK(p);
- }
oldlim = p->p_limit;
alimp = &oldlim->pl_rlimit[which];
if (limp->rlim_cur > alimp->rlim_max ||
limp->rlim_max > alimp->rlim_max)
if ((error = priv_check(td, PRIV_PROC_SETRLIMIT))) {
PROC_UNLOCK(p);
- if (newlim != NULL)
- lim_free(newlim);
+ lim_free(newlim);
return (error);
}
if (limp->rlim_cur > limp->rlim_max)
limp->rlim_cur = limp->rlim_max;
- if (newlim != NULL) {
- lim_copy(newlim, oldlim);
- alimp = &newlim->pl_rlimit[which];
- }
+ lim_copy(newlim, oldlim);
+ alimp = &newlim->pl_rlimit[which];
switch (which) {
@@ -739,11 +727,10 @@ kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
if (p->p_sysent->sv_fixlimit != NULL)
p->p_sysent->sv_fixlimit(limp, which);
*alimp = *limp;
- if (newlim != NULL)
- p->p_limit = newlim;
+ p->p_limit = newlim;
+ PROC_UPDATE_COW(p);
PROC_UNLOCK(p);
- if (newlim != NULL)
- lim_free(oldlim);
+ lim_free(oldlim);
if (which == RLIMIT_STACK &&
/*
@@ -793,15 +780,11 @@ int
sys_getrlimit(struct thread *td, register struct __getrlimit_args *uap)
{
struct rlimit rlim;
- struct proc *p;
int error;
if (uap->which >= RLIM_NLIMITS)
return (EINVAL);
- p = td->td_proc;
- PROC_LOCK(p);
- lim_rlimit(p, uap->which, &rlim);
- PROC_UNLOCK(p);
+ lim_rlimit(td, uap->which, &rlim);
error = copyout(&rlim, uap->rlp, sizeof(struct rlimit));
return (error);
}
@@ -1172,11 +1155,20 @@ lim_copy(struct plimit *dst, struct plimit *src)
* which parameter specifies the index into the rlimit array.
*/
rlim_t
-lim_max(struct proc *p, int which)
+lim_max(struct thread *td, int which)
{
struct rlimit rl;
- lim_rlimit(p, which, &rl);
+ lim_rlimit(td, which, &rl);
+ return (rl.rlim_max);
+}
+
+rlim_t
+lim_max_proc(struct proc *p, int which)
+{
+ struct rlimit rl;
+
+ lim_rlimit_proc(p, which, &rl);
return (rl.rlim_max);
}
@@ -1185,11 +1177,20 @@ lim_max(struct proc *p, int which)
* The which parameter which specifies the index into the rlimit array
*/
rlim_t
-lim_cur(struct proc *p, int which)
+lim_cur(struct thread *td, int which)
{
struct rlimit rl;
- lim_rlimit(p, which, &rl);
+ lim_rlimit(td, which, &rl);
+ return (rl.rlim_cur);
+}
+
+rlim_t
+lim_cur_proc(struct proc *p, int which)
+{
+ struct rlimit rl;
+
+ lim_rlimit_proc(p, which, &rl);
return (rl.rlim_cur);
}
@@ -1198,7 +1199,20 @@ lim_cur(struct proc *p, int which)
* specified by 'which' in the rlimit structure pointed to by 'rlp'.
*/
void
-lim_rlimit(struct proc *p, int which, struct rlimit *rlp)
+lim_rlimit(struct thread *td, int which, struct rlimit *rlp)
+{
+ struct proc *p = td->td_proc;
+
+ MPASS(td == curthread);
+ KASSERT(which >= 0 && which < RLIM_NLIMITS,
+ ("request for invalid resource limit"));
+ *rlp = td->td_limit->pl_rlimit[which];
+ if (p->p_sysent->sv_fixlimit != NULL)
+ p->p_sysent->sv_fixlimit(rlp, which);
+}
+
+void
+lim_rlimit_proc(struct proc *p, int which, struct rlimit *rlp)
{
PROC_LOCK_ASSERT(p, MA_OWNED);
@@ -1441,3 +1455,17 @@ chgkqcnt(struct uidinfo *uip, int diff, rlim_t max)
}
return (1);
}
+
+void
+lim_update_thread(struct thread *td)
+{
+ struct proc *p;
+ struct plimit *lim;
+
+ p = td->td_proc;
+ lim = td->td_limit;
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ td->td_limit = lim_hold(p->p_limit);
+ if (lim != NULL)
+ lim_free(lim);
+}
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index d3cfbdda6c86..f75912b2e9b6 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -300,6 +300,9 @@ __rw_try_wlock(volatile uintptr_t *c, const char *file, int line)
if (rval) {
WITNESS_LOCK(&rw->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
file, line);
+ if (!rw_recursed(rw))
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_WLOCK_ACQUIRE,
+ rw, 0, 0, file, line);
curthread->td_locks++;
}
return (rval);
@@ -352,9 +355,11 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
#endif
uintptr_t v;
#ifdef KDTRACE_HOOKS
+ uintptr_t state;
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
@@ -372,6 +377,10 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
rw->lock_object.lo_name, file, line));
WITNESS_CHECKORDER(&rw->lock_object, LOP_NEWORDER, file, line, NULL);
+#ifdef KDTRACE_HOOKS
+ all_time -= lockstat_nsecs();
+ state = rw->rw_lock;
+#endif
for (;;) {
#ifdef KDTRACE_HOOKS
spin_cnt++;
@@ -534,7 +543,19 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
CTR2(KTR_LOCK, "%s: %p resuming from turnstile",
__func__, rw);
}
+#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
+ if (sleep_time)
+ LOCKSTAT_RECORD4(LS_RW_RLOCK_BLOCK, rw, sleep_time,
+ LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
+ (state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
+ /* Record only the loops spinning and not sleeping. */
+ if (spin_cnt > sleep_cnt)
+ LOCKSTAT_RECORD4(LS_RW_RLOCK_SPIN, rw, all_time - sleep_time,
+ LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
+ (state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
+#endif
/*
* TODO: acquire "owner of record" here. Here be turnstile dragons
* however. turnstiles don't like owners changing between calls to
@@ -546,16 +567,6 @@ __rw_rlock(volatile uintptr_t *c, const char *file, int line)
WITNESS_LOCK(&rw->lock_object, 0, file, line);
curthread->td_locks++;
curthread->td_rw_rlocks++;
-#ifdef KDTRACE_HOOKS
- if (sleep_time)
- LOCKSTAT_RECORD1(LS_RW_RLOCK_BLOCK, rw, sleep_time);
-
- /*
- * Record only the loops spinning and not sleeping.
- */
- if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_RW_RLOCK_SPIN, rw, (spin_cnt - sleep_cnt));
-#endif
}
int
@@ -583,6 +594,8 @@ __rw_try_rlock(volatile uintptr_t *c, const char *file, int line)
LOCK_LOG_TRY("RLOCK", &rw->lock_object, 0, 1, file,
line);
WITNESS_LOCK(&rw->lock_object, LOP_TRYLOCK, file, line);
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_RLOCK_ACQUIRE,
+ rw, 0, 0, file, line);
curthread->td_locks++;
curthread->td_rw_rlocks++;
return (1);
@@ -727,9 +740,11 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
int contested = 0;
#endif
#ifdef KDTRACE_HOOKS
+ uintptr_t state;
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
@@ -751,6 +766,10 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
CTR5(KTR_LOCK, "%s: %s contested (lock=%p) at %s:%d", __func__,
rw->lock_object.lo_name, (void *)rw->rw_lock, file, line);
+#ifdef KDTRACE_HOOKS
+ all_time -= lockstat_nsecs();
+ state = rw->rw_lock;
+#endif
while (!_rw_write_lock(rw, tid)) {
#ifdef KDTRACE_HOOKS
spin_cnt++;
@@ -888,18 +907,21 @@ __rw_wlock_hard(volatile uintptr_t *c, uintptr_t tid, const char *file,
spintries = 0;
#endif
}
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_WLOCK_ACQUIRE, rw, contested,
- waittime, file, line);
#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
if (sleep_time)
- LOCKSTAT_RECORD1(LS_RW_WLOCK_BLOCK, rw, sleep_time);
+ LOCKSTAT_RECORD4(LS_RW_WLOCK_BLOCK, rw, sleep_time,
+ LOCKSTAT_WRITER, (state & RW_LOCK_READ) == 0,
+ (state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
- /*
- * Record only the loops spinning and not sleeping.
- */
+ /* Record only the loops spinning and not sleeping. */
if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_RW_WLOCK_SPIN, rw, (spin_cnt - sleep_cnt));
+ LOCKSTAT_RECORD4(LS_RW_WLOCK_SPIN, rw, all_time - sleep_time,
+ LOCKSTAT_READER, (state & RW_LOCK_READ) == 0,
+ (state & RW_LOCK_READ) == 0 ? 0 : RW_READERS(state));
#endif
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_RW_WLOCK_ACQUIRE, rw, contested,
+ waittime, file, line);
}
/*
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 154c250b4b91..b70da5bd98a2 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2368,9 +2368,12 @@ tdsigwakeup(struct thread *td, int sig, sig_t action, int intrval)
thread_lock(td);
/*
* Bring the priority of a thread up if we want it to get
- * killed in this lifetime.
+ * killed in this lifetime. Be careful to avoid bumping the
+ * priority of the idle thread, since we still allow to signal
+ * kernel processes.
*/
- if (action == SIG_DFL && (prop & SA_KILL) && td->td_priority > PUSER)
+ if (action == SIG_DFL && (prop & SA_KILL) != 0 &&
+ td->td_priority > PUSER && !TD_IS_IDLETHREAD(td))
sched_prio(td, PUSER);
if (TD_ON_SLEEPQ(td)) {
/*
@@ -2408,7 +2411,7 @@ tdsigwakeup(struct thread *td, int sig, sig_t action, int intrval)
/*
* Give low priority threads a better chance to run.
*/
- if (td->td_priority > PUSER)
+ if (td->td_priority > PUSER && !TD_IS_IDLETHREAD(td))
sched_prio(td, PUSER);
wakeup_swapper = sleepq_abort(td, intrval);
@@ -2478,6 +2481,8 @@ ptracestop(struct thread *td, int sig)
td->td_dbgflags |= TDB_XSIG;
td->td_xsig = sig;
+ CTR4(KTR_PTRACE, "ptracestop: tid %d (pid %d) flags %#x sig %d",
+ td->td_tid, p->p_pid, td->td_dbgflags, sig);
PROC_SLOCK(p);
while ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_XSIG)) {
if (p->p_flag & P_SINGLE_EXIT) {
@@ -3304,7 +3309,7 @@ coredump(struct thread *td)
* a corefile is truncated instead of not being created,
* if it is larger than the limit.
*/
- limit = (off_t)lim_cur(p, RLIMIT_CORE);
+ limit = (off_t)lim_cur(td, RLIMIT_CORE);
if (limit == 0 || racct_get_available(p, RACCT_CORE) == 0) {
PROC_UNLOCK(p);
return (EFBIG);
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index a986590ec9b8..91e8c60f899d 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -288,6 +288,8 @@ sx_try_slock_(struct sx *sx, const char *file, int line)
if (atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER)) {
LOCK_LOG_TRY("SLOCK", &sx->lock_object, 0, 1, file, line);
WITNESS_LOCK(&sx->lock_object, LOP_TRYLOCK, file, line);
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_SLOCK_ACQUIRE,
+ sx, 0, 0, file, line);
curthread->td_locks++;
return (1);
}
@@ -348,6 +350,9 @@ sx_try_xlock_(struct sx *sx, const char *file, int line)
if (rval) {
WITNESS_LOCK(&sx->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK,
file, line);
+ if (!sx_recursed(sx))
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_XLOCK_ACQUIRE,
+ sx, 0, 0, file, line);
curthread->td_locks++;
}
@@ -509,9 +514,11 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
#endif
int error = 0;
#ifdef KDTRACE_HOOKS
+ uintptr_t state;
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
@@ -533,6 +540,10 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
CTR5(KTR_LOCK, "%s: %s contested (lock=%p) at %s:%d", __func__,
sx->lock_object.lo_name, (void *)sx->sx_lock, file, line);
+#ifdef KDTRACE_HOOKS
+ all_time -= lockstat_nsecs();
+ state = sx->sx_lock;
+#endif
while (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid)) {
#ifdef KDTRACE_HOOKS
spin_cnt++;
@@ -705,17 +716,21 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file,
CTR2(KTR_LOCK, "%s: %p resuming from sleep queue",
__func__, sx);
}
-
- GIANT_RESTORE();
- if (!error)
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_XLOCK_ACQUIRE, sx,
- contested, waittime, file, line);
#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
if (sleep_time)
- LOCKSTAT_RECORD1(LS_SX_XLOCK_BLOCK, sx, sleep_time);
+ LOCKSTAT_RECORD4(LS_SX_XLOCK_BLOCK, sx, sleep_time,
+ LOCKSTAT_WRITER, (state & SX_LOCK_SHARED) == 0,
+ (state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_SX_XLOCK_SPIN, sx, (spin_cnt - sleep_cnt));
+ LOCKSTAT_RECORD4(LS_SX_XLOCK_SPIN, sx, all_time - sleep_time,
+ LOCKSTAT_WRITER, (state & SX_LOCK_SHARED) == 0,
+ (state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
#endif
+ if (!error)
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_XLOCK_ACQUIRE, sx,
+ contested, waittime, file, line);
+ GIANT_RESTORE();
return (error);
}
@@ -801,14 +816,21 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
uintptr_t x;
int error = 0;
#ifdef KDTRACE_HOOKS
+ uintptr_t state;
uint64_t spin_cnt = 0;
uint64_t sleep_cnt = 0;
int64_t sleep_time = 0;
+ int64_t all_time = 0;
#endif
if (SCHEDULER_STOPPED())
return (0);
+#ifdef KDTRACE_HOOKS
+ state = sx->sx_lock;
+ all_time -= lockstat_nsecs();
+#endif
+
/*
* As with rwlocks, we don't make any attempt to try to block
* shared locks once there is an exclusive waiter.
@@ -958,15 +980,20 @@ _sx_slock_hard(struct sx *sx, int opts, const char *file, int line)
CTR2(KTR_LOCK, "%s: %p resuming from sleep queue",
__func__, sx);
}
- if (error == 0)
- LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_SLOCK_ACQUIRE, sx,
- contested, waittime, file, line);
#ifdef KDTRACE_HOOKS
+ all_time += lockstat_nsecs();
if (sleep_time)
- LOCKSTAT_RECORD1(LS_SX_XLOCK_BLOCK, sx, sleep_time);
+ LOCKSTAT_RECORD4(LS_SX_SLOCK_BLOCK, sx, sleep_time,
+ LOCKSTAT_READER, (state & SX_LOCK_SHARED) == 0,
+ (state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
if (spin_cnt > sleep_cnt)
- LOCKSTAT_RECORD1(LS_SX_XLOCK_SPIN, sx, (spin_cnt - sleep_cnt));
+ LOCKSTAT_RECORD4(LS_SX_SLOCK_SPIN, sx, all_time - sleep_time,
+ LOCKSTAT_READER, (state & SX_LOCK_SHARED) == 0,
+ (state & SX_LOCK_SHARED) == 0 ? 0 : SX_SHARERS(state));
#endif
+ if (error == 0)
+ LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_SLOCK_ACQUIRE, sx,
+ contested, waittime, file, line);
GIANT_RESTORE();
return (error);
}
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index e0ee2dc0dc86..8c847736f9da 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -414,11 +414,9 @@ mi_switch(int flags, struct thread *newtd)
{
uint64_t runtime, new_switchtime;
struct thread *td;
- struct proc *p;
td = curthread; /* XXX */
THREAD_LOCK_ASSERT(td, MA_OWNED | MA_NOTRECURSED);
- p = td->td_proc; /* XXX */
KASSERT(!TD_ON_RUNQ(td), ("mi_switch: called by old code"));
#ifdef INVARIANTS
if (!TD_ON_LOCK(td) && !TD_IS_RUNNING(td))
@@ -458,7 +456,7 @@ mi_switch(int flags, struct thread *newtd)
PCPU_INC(cnt.v_swtch);
PCPU_SET(switchticks, ticks);
CTR4(KTR_PROC, "mi_switch: old thread %ld (td_sched %p, pid %ld, %s)",
- td->td_tid, td->td_sched, p->p_pid, td->td_name);
+ td->td_tid, td->td_sched, td->td_proc->p_pid, td->td_name);
#if (KTR_COMPILE & KTR_SCHED) != 0
if (TD_IS_IDLETHREAD(td))
KTR_STATE1(KTR_SCHED, "thread", sched_tdname(td), "idle",
@@ -474,7 +472,7 @@ mi_switch(int flags, struct thread *newtd)
"prio:%d", td->td_priority);
CTR4(KTR_PROC, "mi_switch: new thread %ld (td_sched %p, pid %ld, %s)",
- td->td_tid, td->td_sched, p->p_pid, td->td_name);
+ td->td_tid, td->td_sched, td->td_proc->p_pid, td->td_name);
/*
* If the last thread was exiting, finish cleaning it up.
diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c
index dada746df2da..15574beb45c5 100644
--- a/sys/kern/kern_syscalls.c
+++ b/sys/kern/kern_syscalls.c
@@ -31,6 +31,9 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/resourcevar.h>
#include <sys/sx.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 9dca0e80e5ea..eba0b603658a 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -71,7 +71,7 @@ struct timehands {
struct timeval th_microtime;
struct timespec th_nanotime;
/* Fields not to be copied in tc_windup start with th_generation. */
- volatile u_int th_generation;
+ u_int th_generation;
struct timehands *th_next;
};
@@ -189,6 +189,33 @@ tc_delta(struct timehands *th)
tc->tc_counter_mask);
}
+static inline u_int
+tc_getgen(struct timehands *th)
+{
+
+#ifdef SMP
+ return (atomic_load_acq_int(&th->th_generation));
+#else
+ u_int gen;
+
+ gen = th->th_generation;
+ __compiler_membar();
+ return (gen);
+#endif
+}
+
+static inline void
+tc_setgen(struct timehands *th, u_int newgen)
+{
+
+#ifdef SMP
+ atomic_store_rel_int(&th->th_generation, newgen);
+#else
+ __compiler_membar();
+ th->th_generation = newgen;
+#endif
+}
+
/*
* Functions for reading the time. We have to loop until we are sure that
* the timehands that we operated on was not updated under our feet. See
@@ -204,10 +231,10 @@ fbclock_binuptime(struct bintime *bt)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*bt = th->th_offset;
bintime_addx(bt, th->th_scale * tc_delta(th));
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -262,9 +289,9 @@ fbclock_getbinuptime(struct bintime *bt)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*bt = th->th_offset;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -275,9 +302,9 @@ fbclock_getnanouptime(struct timespec *tsp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
bintime2timespec(&th->th_offset, tsp);
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -288,9 +315,9 @@ fbclock_getmicrouptime(struct timeval *tvp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
bintime2timeval(&th->th_offset, tvp);
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -301,9 +328,9 @@ fbclock_getbintime(struct bintime *bt)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*bt = th->th_offset;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
bintime_add(bt, &boottimebin);
}
@@ -315,9 +342,9 @@ fbclock_getnanotime(struct timespec *tsp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*tsp = th->th_nanotime;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -328,9 +355,9 @@ fbclock_getmicrotime(struct timeval *tvp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*tvp = th->th_microtime;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
#else /* !FFCLOCK */
void
@@ -341,10 +368,10 @@ binuptime(struct bintime *bt)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*bt = th->th_offset;
bintime_addx(bt, th->th_scale * tc_delta(th));
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -399,9 +426,9 @@ getbinuptime(struct bintime *bt)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*bt = th->th_offset;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -412,9 +439,9 @@ getnanouptime(struct timespec *tsp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
bintime2timespec(&th->th_offset, tsp);
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -425,9 +452,9 @@ getmicrouptime(struct timeval *tvp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
bintime2timeval(&th->th_offset, tvp);
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -438,9 +465,9 @@ getbintime(struct bintime *bt)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*bt = th->th_offset;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
bintime_add(bt, &boottimebin);
}
@@ -452,9 +479,9 @@ getnanotime(struct timespec *tsp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*tsp = th->th_nanotime;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
void
@@ -465,9 +492,9 @@ getmicrotime(struct timeval *tvp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*tvp = th->th_microtime;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
#endif /* FFCLOCK */
@@ -880,11 +907,11 @@ ffclock_read_counter(ffcounter *ffcount)
*/
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
ffth = fftimehands;
delta = tc_delta(th);
*ffcount = ffth->tick_ffcount;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
*ffcount += delta;
}
@@ -988,9 +1015,9 @@ dtrace_getnanotime(struct timespec *tsp)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
*tsp = th->th_nanotime;
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
}
/*
@@ -1028,7 +1055,7 @@ sysclock_getsnapshot(struct sysclock_snap *clock_snap, int fast)
do {
th = timehands;
- gen = th->th_generation;
+ gen = tc_getgen(th);
fbi->th_scale = th->th_scale;
fbi->tick_time = th->th_offset;
#ifdef FFCLOCK
@@ -1042,7 +1069,7 @@ sysclock_getsnapshot(struct sysclock_snap *clock_snap, int fast)
#endif
if (!fast)
delta = tc_delta(th);
- } while (gen == 0 || gen != th->th_generation);
+ } while (gen == 0 || gen != tc_getgen(th));
clock_snap->delta = delta;
clock_snap->sysclock_active = sysclock_active;
@@ -1260,7 +1287,7 @@ tc_windup(void)
tho = timehands;
th = tho->th_next;
ogen = th->th_generation;
- th->th_generation = 0;
+ tc_setgen(th, 0);
bcopy(tho, th, offsetof(struct timehands, th_generation));
/*
@@ -1377,7 +1404,7 @@ tc_windup(void)
*/
if (++ogen == 0)
ogen = 1;
- th->th_generation = ogen;
+ tc_setgen(th, ogen);
/* Go live with the new struct timehands. */
#ifdef FFCLOCK
@@ -1651,13 +1678,13 @@ pps_capture(struct pps_state *pps)
KASSERT(pps != NULL, ("NULL pps pointer in pps_capture"));
th = timehands;
- pps->capgen = th->th_generation;
+ pps->capgen = tc_getgen(th);
pps->capth = th;
#ifdef FFCLOCK
pps->capffth = fftimehands;
#endif
pps->capcount = th->th_counter->tc_get_timecount(th->th_counter);
- if (pps->capgen != th->th_generation)
+ if (pps->capgen != tc_getgen(th))
pps->capgen = 0;
}
@@ -1677,7 +1704,7 @@ pps_event(struct pps_state *pps, int event)
KASSERT(pps != NULL, ("NULL pps pointer in pps_event"));
/* If the timecounter was wound up underneath us, bail out. */
- if (pps->capgen == 0 || pps->capgen != pps->capth->th_generation)
+ if (pps->capgen == 0 || pps->capgen != tc_getgen(pps->capth))
return;
/* Things would be easier with arrays. */
@@ -1727,7 +1754,7 @@ pps_event(struct pps_state *pps, int event)
bintime2timespec(&bt, &ts);
/* If the timecounter was wound up underneath us, bail out. */
- if (pps->capgen != pps->capth->th_generation)
+ if (pps->capgen != tc_getgen(pps->capth))
return;
*pcount = pps->capcount;
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c
index 6911bb97b3df..e6b0a59fcc7a 100644
--- a/sys/kern/kern_thr.c
+++ b/sys/kern/kern_thr.c
@@ -162,12 +162,6 @@ create_thread(struct thread *td, mcontext_t *ctx,
p = td->td_proc;
- /* Have race condition but it is cheap. */
- if (p->p_numthreads >= max_threads_per_proc) {
- ++max_threads_hits;
- return (EPROCLIM);
- }
-
if (rtp != NULL) {
switch(rtp->type) {
case RTP_PRIO_REALTIME:
@@ -197,11 +191,9 @@ create_thread(struct thread *td, mcontext_t *ctx,
#endif
/* Initialize our td */
- newtd = thread_alloc(0);
- if (newtd == NULL) {
- error = ENOMEM;
+ error = kern_thr_alloc(p, 0, &newtd);
+ if (error)
goto fail;
- }
cpu_set_upcall(newtd, td);
@@ -228,13 +220,13 @@ create_thread(struct thread *td, mcontext_t *ctx,
bcopy(&td->td_startcopy, &newtd->td_startcopy,
__rangeof(struct thread, td_startcopy, td_endcopy));
newtd->td_proc = td->td_proc;
- newtd->td_ucred = crhold(td->td_ucred);
+ thread_cow_get(newtd, td);
if (ctx != NULL) { /* old way to set user context */
error = set_mcontext(newtd, ctx);
if (error != 0) {
+ thread_cow_free(newtd);
thread_free(newtd);
- crfree(td->td_ucred);
goto fail;
}
} else {
@@ -246,8 +238,8 @@ create_thread(struct thread *td, mcontext_t *ctx,
/* Setup user TLS address and TLS pointer register. */
error = cpu_set_user_tls(newtd, tls_base);
if (error != 0) {
+ thread_cow_free(newtd);
thread_free(newtd);
- crfree(td->td_ucred);
goto fail;
}
}
@@ -307,9 +299,6 @@ int
sys_thr_exit(struct thread *td, struct thr_exit_args *uap)
/* long *state */
{
- struct proc *p;
-
- p = td->td_proc;
/* Signal userland that it can free the stack. */
if ((void *)uap->state != NULL) {
@@ -317,8 +306,17 @@ sys_thr_exit(struct thread *td, struct thr_exit_args *uap)
kern_umtx_wake(td, uap->state, INT_MAX, 0);
}
- rw_wlock(&tidhash_lock);
+ return (kern_thr_exit(td));
+}
+
+int
+kern_thr_exit(struct thread *td)
+{
+ struct proc *p;
+ p = td->td_proc;
+
+ rw_wlock(&tidhash_lock);
PROC_LOCK(p);
if (p->p_numthreads != 1) {
@@ -560,3 +558,20 @@ sys_thr_set_name(struct thread *td, struct thr_set_name_args *uap)
PROC_UNLOCK(p);
return (error);
}
+
+int
+kern_thr_alloc(struct proc *p, int pages, struct thread **ntd)
+{
+
+ /* Have race condition but it is cheap. */
+ if (p->p_numthreads >= max_threads_per_proc) {
+ ++max_threads_hits;
+ return (EPROCLIM);
+ }
+
+ *ntd = thread_alloc(pages);
+ if (*ntd == NULL)
+ return (ENOMEM);
+
+ return (0);
+}
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 0dd5f4633ae5..4343b643c867 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sched.h>
#include <sys/sleepqueue.h>
#include <sys/selinfo.h>
+#include <sys/sysent.h>
#include <sys/turnstile.h>
#include <sys/ktr.h>
#include <sys/rwlock.h>
@@ -326,8 +327,7 @@ thread_reap(void)
mtx_unlock_spin(&zombie_lock);
while (td_first) {
td_next = TAILQ_NEXT(td_first, td_slpq);
- if (td_first->td_ucred)
- crfree(td_first->td_ucred);
+ thread_cow_free(td_first);
thread_free(td_first);
td_first = td_next;
}
@@ -383,6 +383,50 @@ thread_free(struct thread *td)
uma_zfree(thread_zone, td);
}
+void
+thread_cow_get_proc(struct thread *newtd, struct proc *p)
+{
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ newtd->td_ucred = crhold(p->p_ucred);
+ newtd->td_limit = lim_hold(p->p_limit);
+ newtd->td_cowgen = p->p_cowgen;
+}
+
+void
+thread_cow_get(struct thread *newtd, struct thread *td)
+{
+
+ newtd->td_ucred = crhold(td->td_ucred);
+ newtd->td_limit = lim_hold(td->td_limit);
+ newtd->td_cowgen = td->td_cowgen;
+}
+
+void
+thread_cow_free(struct thread *td)
+{
+
+ if (td->td_ucred)
+ crfree(td->td_ucred);
+ if (td->td_limit)
+ lim_free(td->td_limit);
+}
+
+void
+thread_cow_update(struct thread *td)
+{
+ struct proc *p;
+
+ p = td->td_proc;
+ PROC_LOCK(p);
+ if (td->td_ucred != p->p_ucred)
+ cred_update_thread(td);
+ if (td->td_limit != p->p_limit)
+ lim_update_thread(td);
+ td->td_cowgen = p->p_cowgen;
+ PROC_UNLOCK(p);
+}
+
/*
* Discard the current thread and exit from its context.
* Always called with scheduler locked.
@@ -520,7 +564,7 @@ thread_wait(struct proc *p)
cpuset_rel(td->td_cpuset);
td->td_cpuset = NULL;
cpu_thread_clean(td);
- crfree(td->td_ucred);
+ thread_cow_free(td);
thread_reap(); /* check for zombie threads etc. */
}
@@ -884,6 +928,14 @@ thread_suspend_check(int return_instead)
if ((p->p_flag & P_SINGLE_EXIT) && (p->p_singlethread != td)) {
PROC_UNLOCK(p);
tidhash_remove(td);
+
+ /*
+ * Allow Linux emulation layer to do some work
+ * before thread suicide.
+ */
+ if (__predict_false(p->p_sysent->sv_thread_detach != NULL))
+ (p->p_sysent->sv_thread_detach)(td);
+
PROC_LOCK(p);
tdsigcleanup(td);
umtx_thread_exit(td);
diff --git a/sys/kern/p1003_1b.c b/sys/kern/p1003_1b.c
index fb89efc5e00f..ac6cd60a5d6e 100644
--- a/sys/kern/p1003_1b.c
+++ b/sys/kern/p1003_1b.c
@@ -130,16 +130,29 @@ sys_sched_setparam(struct thread *td, struct sched_setparam_args *uap)
targettd = FIRST_THREAD_IN_PROC(targetp);
}
- e = p_cansched(td, targetp);
- if (e == 0) {
- e = ksched_setparam(ksched, targettd,
- (const struct sched_param *)&sched_param);
- }
+ e = kern_sched_setparam(td, targettd, &sched_param);
PROC_UNLOCK(targetp);
return (e);
}
int
+kern_sched_setparam(struct thread *td, struct thread *targettd,
+ struct sched_param *param)
+{
+ struct proc *targetp;
+ int error;
+
+ targetp = targettd->td_proc;
+ PROC_LOCK_ASSERT(targetp, MA_OWNED);
+
+ error = p_cansched(td, targetp);
+ if (error == 0)
+ error = ksched_setparam(ksched, targettd,
+ (const struct sched_param *)param);
+ return (error);
+}
+
+int
sys_sched_getparam(struct thread *td, struct sched_getparam_args *uap)
{
int e;
@@ -159,10 +172,7 @@ sys_sched_getparam(struct thread *td, struct sched_getparam_args *uap)
targettd = FIRST_THREAD_IN_PROC(targetp);
}
- e = p_cansee(td, targetp);
- if (e == 0) {
- e = ksched_getparam(ksched, targettd, &sched_param);
- }
+ e = kern_sched_getparam(td, targettd, &sched_param);
PROC_UNLOCK(targetp);
if (e == 0)
e = copyout(&sched_param, uap->param, sizeof(sched_param));
@@ -170,6 +180,22 @@ sys_sched_getparam(struct thread *td, struct sched_getparam_args *uap)
}
int
+kern_sched_getparam(struct thread *td, struct thread *targettd,
+ struct sched_param *param)
+{
+ struct proc *targetp;
+ int error;
+
+ targetp = targettd->td_proc;
+ PROC_LOCK_ASSERT(targetp, MA_OWNED);
+
+ error = p_cansee(td, targetp);
+ if (error == 0)
+ error = ksched_getparam(ksched, targettd, param);
+ return (error);
+}
+
+int
sys_sched_setscheduler(struct thread *td, struct sched_setscheduler_args *uap)
{
int e;
@@ -177,11 +203,6 @@ sys_sched_setscheduler(struct thread *td, struct sched_setscheduler_args *uap)
struct thread *targettd;
struct proc *targetp;
- /* Don't allow non root user to set a scheduler policy. */
- e = priv_check(td, PRIV_SCHED_SET);
- if (e)
- return (e);
-
e = copyin(uap->param, &sched_param, sizeof(sched_param));
if (e)
return (e);
@@ -197,16 +218,35 @@ sys_sched_setscheduler(struct thread *td, struct sched_setscheduler_args *uap)
targettd = FIRST_THREAD_IN_PROC(targetp);
}
- e = p_cansched(td, targetp);
- if (e == 0) {
- e = ksched_setscheduler(ksched, targettd,
- uap->policy, (const struct sched_param *)&sched_param);
- }
+ e = kern_sched_setscheduler(td, targettd, uap->policy,
+ &sched_param);
PROC_UNLOCK(targetp);
return (e);
}
int
+kern_sched_setscheduler(struct thread *td, struct thread *targettd,
+ int policy, struct sched_param *param)
+{
+ struct proc *targetp;
+ int error;
+
+ targetp = targettd->td_proc;
+ PROC_LOCK_ASSERT(targetp, MA_OWNED);
+
+ /* Don't allow non root user to set a scheduler policy. */
+ error = priv_check(td, PRIV_SCHED_SET);
+ if (error)
+ return (error);
+
+ error = p_cansched(td, targetp);
+ if (error == 0)
+ error = ksched_setscheduler(ksched, targettd, policy,
+ (const struct sched_param *)param);
+ return (error);
+}
+
+int
sys_sched_getscheduler(struct thread *td, struct sched_getscheduler_args *uap)
{
int e, policy;
@@ -224,17 +264,31 @@ sys_sched_getscheduler(struct thread *td, struct sched_getscheduler_args *uap)
targettd = FIRST_THREAD_IN_PROC(targetp);
}
- e = p_cansee(td, targetp);
- if (e == 0) {
- e = ksched_getscheduler(ksched, targettd, &policy);
- td->td_retval[0] = policy;
- }
+ e = kern_sched_getscheduler(td, targettd, &policy);
PROC_UNLOCK(targetp);
+ if (e == 0)
+ td->td_retval[0] = policy;
return (e);
}
int
+kern_sched_getscheduler(struct thread *td, struct thread *targettd,
+ int *policy)
+{
+ struct proc *targetp;
+ int error;
+
+ targetp = targettd->td_proc;
+ PROC_LOCK_ASSERT(targetp, MA_OWNED);
+
+ error = p_cansee(td, targetp);
+ if (error == 0)
+ error = ksched_getscheduler(ksched, targettd, policy);
+ return (error);
+}
+
+int
sys_sched_yield(struct thread *td, struct sched_yield_args *uap)
{
@@ -296,13 +350,26 @@ kern_sched_rr_get_interval(struct thread *td, pid_t pid,
targettd = FIRST_THREAD_IN_PROC(targetp);
}
- e = p_cansee(td, targetp);
- if (e == 0)
- e = ksched_rr_get_interval(ksched, targettd, ts);
+ e = kern_sched_rr_get_interval_td(td, targettd, ts);
PROC_UNLOCK(targetp);
return (e);
}
+int
+kern_sched_rr_get_interval_td(struct thread *td, struct thread *targettd,
+ struct timespec *ts)
+{
+ struct proc *p;
+ int error;
+
+ p = targettd->td_proc;
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+
+ error = p_cansee(td, p);
+ if (error == 0)
+ error = ksched_rr_get_interval(ksched, targettd, ts);
+ return (error);
+}
#endif
static void
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 65095228083c..4f35838a75ef 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -37,10 +37,13 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#ifdef _KERNEL
#include "opt_ddb.h"
#include "opt_printf.h"
+#endif /* _KERNEL */
#include <sys/param.h>
+#ifdef _KERNEL
#include <sys/systm.h>
#include <sys/lock.h>
#include <sys/kdb.h>
@@ -57,7 +60,9 @@ __FBSDID("$FreeBSD$");
#include <sys/syslog.h>
#include <sys/cons.h>
#include <sys/uio.h>
+#endif
#include <sys/ctype.h>
+#include <sys/sbuf.h>
#ifdef DDB
#include <ddb/ddb.h>
@@ -69,6 +74,8 @@ __FBSDID("$FreeBSD$");
*/
#include <machine/stdarg.h>
+#ifdef _KERNEL
+
#define TOCONS 0x01
#define TOTTY 0x02
#define TOLOG 0x04
@@ -1119,3 +1126,59 @@ hexdump(const void *ptr, int length, const char *hdr, int flags)
printf("\n");
}
}
+#endif /* _KERNEL */
+
+void
+sbuf_hexdump(struct sbuf *sb, const void *ptr, int length, const char *hdr,
+ int flags)
+{
+ int i, j, k;
+ int cols;
+ const unsigned char *cp;
+ char delim;
+
+ if ((flags & HD_DELIM_MASK) != 0)
+ delim = (flags & HD_DELIM_MASK) >> 8;
+ else
+ delim = ' ';
+
+ if ((flags & HD_COLUMN_MASK) != 0)
+ cols = flags & HD_COLUMN_MASK;
+ else
+ cols = 16;
+
+ cp = ptr;
+ for (i = 0; i < length; i+= cols) {
+ if (hdr != NULL)
+ sbuf_printf(sb, "%s", hdr);
+
+ if ((flags & HD_OMIT_COUNT) == 0)
+ sbuf_printf(sb, "%04x ", i);
+
+ if ((flags & HD_OMIT_HEX) == 0) {
+ for (j = 0; j < cols; j++) {
+ k = i + j;
+ if (k < length)
+ sbuf_printf(sb, "%c%02x", delim, cp[k]);
+ else
+ sbuf_printf(sb, " ");
+ }
+ }
+
+ if ((flags & HD_OMIT_CHARS) == 0) {
+ sbuf_printf(sb, " |");
+ for (j = 0; j < cols; j++) {
+ k = i + j;
+ if (k >= length)
+ sbuf_printf(sb, " ");
+ else if (cp[k] >= ' ' && cp[k] <= '~')
+ sbuf_printf(sb, "%c", cp[k]);
+ else
+ sbuf_printf(sb, ".");
+ }
+ sbuf_printf(sb, "|");
+ }
+ sbuf_printf(sb, "\n");
+ }
+}
+
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index 1bf78b852e5f..070ba281cbaf 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -61,8 +61,8 @@ syscallenter(struct thread *td, struct syscall_args *sa)
p = td->td_proc;
td->td_pticks = 0;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
if (p->p_flag & P_TRACED) {
traced = 1;
PROC_LOCK(p);
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c
index 2cf1f63d9a21..f0a5a1ba85e4 100644
--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -323,17 +323,16 @@ taskqueue_drain_tq_queue(struct taskqueue *queue)
return;
/*
- * Enqueue our barrier with the lowest possible priority
- * so we are inserted after all current tasks.
+ * Enqueue our barrier after all current tasks, but with
+ * the highest priority so that newly queued tasks cannot
+ * pass it. Because of the high priority, we can not use
+ * taskqueue_enqueue_locked directly (which drops the lock
+ * anyway) so just insert it at tail while we have the
+ * queue lock.
*/
- TASK_INIT(&t_barrier, 0, taskqueue_task_nop_fn, &t_barrier);
- taskqueue_enqueue_locked(queue, &t_barrier);
-
- /*
- * Raise the barrier's priority so newly queued tasks cannot
- * pass it.
- */
- t_barrier.ta_priority = USHRT_MAX;
+ TASK_INIT(&t_barrier, USHRT_MAX, taskqueue_task_nop_fn, &t_barrier);
+ STAILQ_INSERT_TAIL(&queue->tq_queue, &t_barrier, ta_link);
+ t_barrier.ta_pending = 1;
/*
* Once the barrier has executed, all previously queued tasks
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 93f7557aef63..375bb321485d 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -86,6 +86,8 @@ __FBSDID("$FreeBSD$");
#include <security/mac/mac_framework.h>
+void (*softdep_ast_cleanup)(void);
+
/*
* Define the code needed before returning to user mode, for trap and
* syscall.
@@ -114,6 +116,9 @@ userret(struct thread *td, struct trapframe *frame)
#ifdef KTRACE
KTRUSERRET(td);
#endif
+ if (softdep_ast_cleanup != NULL)
+ softdep_ast_cleanup();
+
/*
* If this thread tickled GEOM, we need to wait for the giggling to
* stop before we return to userland
@@ -157,6 +162,8 @@ userret(struct thread *td, struct trapframe *frame)
("userret: Returning while holding vnode reservation"));
KASSERT((td->td_flags & TDF_SBDRY) == 0,
("userret: Returning with stop signals deferred"));
+ KASSERT(td->td_su == NULL,
+ ("userret: Returning with SU cleanup request not handled"));
#ifdef VIMAGE
/* Unfortunately td_vnet_lpush needs VNET_DEBUG. */
VNET_ASSERT(curvnet == NULL,
@@ -213,8 +220,8 @@ ast(struct trapframe *framep)
thread_unlock(td);
PCPU_INC(cnt.v_trap);
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
if (td->td_pflags & TDP_OWEUPC && p->p_flag & P_PROFIL) {
addupc_task(td, td->td_profil_addr, td->td_profil_ticks);
td->td_profil_ticks = 0;
diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c
index 87892fd82798..aac6eb6f5e94 100644
--- a/sys/kern/subr_uio.c
+++ b/sys/kern/subr_uio.c
@@ -409,15 +409,13 @@ copyout_map(struct thread *td, vm_offset_t *addr, size_t sz)
/*
* Map somewhere after heap in process memory.
*/
- PROC_LOCK(td->td_proc);
*addr = round_page((vm_offset_t)vms->vm_daddr +
- lim_max(td->td_proc, RLIMIT_DATA));
- PROC_UNLOCK(td->td_proc);
+ lim_max(td, RLIMIT_DATA));
/* round size up to page boundry */
size = (vm_size_t)round_page(sz);
- error = vm_mmap(&vms->vm_map, addr, size, PROT_READ | PROT_WRITE,
+ error = vm_mmap(&vms->vm_map, addr, size, VM_PROT_READ | VM_PROT_WRITE,
VM_PROT_ALL, MAP_PRIVATE | MAP_ANON, OBJT_DEFAULT, NULL, 0);
return (error);
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index dc343d0162c6..12808073387e 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -1170,19 +1170,25 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
/*
* Try to perform most checks without a lock. If this succeeds we
- * can skip acquiring the lock and return success.
+ * can skip acquiring the lock and return success. Otherwise we redo
+ * the check with the lock held to handle races with concurrent updates.
*/
w1 = plock->li_lock->lo_witness;
if (witness_lock_order_check(w1, w))
return;
+ mtx_lock_spin(&w_mtx);
+ if (witness_lock_order_check(w1, w)) {
+ mtx_unlock_spin(&w_mtx);
+ return;
+ }
+ witness_lock_order_add(w1, w);
+
/*
* Check for duplicate locks of the same type. Note that we only
* have to check for this on the last lock we just acquired. Any
* other cases will be caught as lock order violations.
*/
- mtx_lock_spin(&w_mtx);
- witness_lock_order_add(w1, w);
if (w1 == w) {
i = w->w_index;
if (!(lock->lo_flags & LO_DUPOK) && !(flags & LOP_DUPOK) &&
@@ -1996,7 +2002,10 @@ _isitmyx(struct witness *w1, struct witness *w2, int rmask, const char *fname)
/* The flags on one better be the inverse of the flags on the other */
if (!((WITNESS_ATOD(r1) == r2 && WITNESS_DTOA(r2) == r1) ||
- (WITNESS_DTOA(r1) == r2 && WITNESS_ATOD(r2) == r1))) {
+ (WITNESS_DTOA(r1) == r2 && WITNESS_ATOD(r2) == r1))) {
+ /* Don't squawk if we're potentially racing with an update. */
+ if (!mtx_owned(&w_mtx))
+ return (0);
printf("%s: rmatrix mismatch between %s (index %d) and %s "
"(index %d): w_rmatrix[%d][%d] == %hhx but "
"w_rmatrix[%d][%d] == %hhx\n",
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 7dd3d1754361..d82fda030cb8 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -402,7 +402,7 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
lobj = tobj;
pve->pve_offset += tobj->backing_object_offset;
}
- vp = (lobj->type == OBJT_VNODE) ? lobj->handle : NULL;
+ vp = vm_object_vnode(lobj);
if (vp != NULL)
vref(vp);
if (lobj != obj)
@@ -432,6 +432,9 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
free(freepath, M_TEMP);
}
}
+ if (error == 0)
+ CTR3(KTR_PTRACE, "PT_VM_ENTRY: pid %d, entry %d, start %p",
+ p->p_pid, pve->pve_entry, pve->pve_start);
return (error);
}
@@ -826,6 +829,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
if (p->p_flag & P_PPWAIT)
p->p_flag |= P_PPTRACE;
p->p_oppid = p->p_pptr->p_pid;
+ CTR1(KTR_PTRACE, "PT_TRACE_ME: pid %d", p->p_pid);
break;
case PT_ATTACH:
@@ -845,17 +849,25 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
proc_reparent(p, td->td_proc);
}
data = SIGSTOP;
+ CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid,
+ p->p_oppid);
goto sendsig; /* in PT_CONTINUE below */
case PT_CLEARSTEP:
+ CTR2(KTR_PTRACE, "PT_CLEARSTEP: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
error = ptrace_clear_single_step(td2);
break;
case PT_SETSTEP:
+ CTR2(KTR_PTRACE, "PT_SETSTEP: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
error = ptrace_single_step(td2);
break;
case PT_SUSPEND:
+ CTR2(KTR_PTRACE, "PT_SUSPEND: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
td2->td_dbgflags |= TDB_SUSPEND;
thread_lock(td2);
td2->td_flags |= TDF_NEEDSUSPCHK;
@@ -863,10 +875,15 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
break;
case PT_RESUME:
+ CTR2(KTR_PTRACE, "PT_RESUME: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
td2->td_dbgflags &= ~TDB_SUSPEND;
break;
case PT_FOLLOW_FORK:
+ CTR3(KTR_PTRACE, "PT_FOLLOW_FORK: pid %d %s -> %s", p->p_pid,
+ p->p_flag & P_FOLLOWFORK ? "enabled" : "disabled",
+ data ? "enabled" : "disabled");
if (data)
p->p_flag |= P_FOLLOWFORK;
else
@@ -887,6 +904,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
switch (req) {
case PT_STEP:
+ CTR2(KTR_PTRACE, "PT_STEP: tid %d (pid %d)",
+ td2->td_tid, p->p_pid);
error = ptrace_single_step(td2);
if (error)
goto out;
@@ -904,12 +923,25 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
switch (req) {
case PT_TO_SCE:
p->p_stops |= S_PT_SCE;
+ CTR2(KTR_PTRACE,
+ "PT_TO_SCE: pid %d, stops = %#x", p->p_pid,
+ p->p_stops);
break;
case PT_TO_SCX:
p->p_stops |= S_PT_SCX;
+ CTR2(KTR_PTRACE,
+ "PT_TO_SCX: pid %d, stops = %#x", p->p_pid,
+ p->p_stops);
break;
case PT_SYSCALL:
p->p_stops |= S_PT_SCE | S_PT_SCX;
+ CTR2(KTR_PTRACE,
+ "PT_SYSCALL: pid %d, stops = %#x", p->p_pid,
+ p->p_stops);
+ break;
+ case PT_CONTINUE:
+ CTR1(KTR_PTRACE,
+ "PT_CONTINUE: pid %d", p->p_pid);
break;
}
break;
@@ -924,9 +956,14 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
proc_reparent(p, pp);
if (pp == initproc)
p->p_sigparent = SIGCHLD;
- }
+ CTR2(KTR_PTRACE,
+ "PT_DETACH: pid %d reparented to pid %d",
+ p->p_pid, pp->p_pid);
+ } else
+ CTR1(KTR_PTRACE, "PT_DETACH: pid %d", p->p_pid);
p->p_oppid = 0;
p->p_flag &= ~(P_TRACED | P_WAITED | P_FOLLOWFORK);
+ p->p_stops = 0;
/* should we send SIGCHLD? */
/* childproc_continued(p); */
@@ -1001,6 +1038,14 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
}
if (!write)
td->td_retval[0] = tmp;
+ if (error == 0) {
+ if (write)
+ CTR3(KTR_PTRACE, "PT_WRITE: pid %d: %p <= %#x",
+ p->p_pid, addr, data);
+ else
+ CTR3(KTR_PTRACE, "PT_READ: pid %d: %p >= %#x",
+ p->p_pid, addr, tmp);
+ }
PROC_LOCK(p);
break;
@@ -1033,10 +1078,14 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
switch (tmp) {
case PIOD_READ_D:
case PIOD_READ_I:
+ CTR3(KTR_PTRACE, "PT_IO: pid %d: READ (%p, %#x)",
+ p->p_pid, (uintptr_t)uio.uio_offset, uio.uio_resid);
uio.uio_rw = UIO_READ;
break;
case PIOD_WRITE_D:
case PIOD_WRITE_I:
+ CTR3(KTR_PTRACE, "PT_IO: pid %d: WRITE (%p, %#x)",
+ p->p_pid, (uintptr_t)uio.uio_offset, uio.uio_resid);
td2->td_dbgflags |= TDB_USERWR;
uio.uio_rw = UIO_WRITE;
break;
@@ -1056,33 +1105,46 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
break;
case PT_KILL:
+ CTR1(KTR_PTRACE, "PT_KILL: pid %d", p->p_pid);
data = SIGKILL;
goto sendsig; /* in PT_CONTINUE above */
case PT_SETREGS:
+ CTR2(KTR_PTRACE, "PT_SETREGS: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
td2->td_dbgflags |= TDB_USERWR;
error = PROC_WRITE(regs, td2, addr);
break;
case PT_GETREGS:
+ CTR2(KTR_PTRACE, "PT_GETREGS: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
error = PROC_READ(regs, td2, addr);
break;
case PT_SETFPREGS:
+ CTR2(KTR_PTRACE, "PT_SETFPREGS: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
td2->td_dbgflags |= TDB_USERWR;
error = PROC_WRITE(fpregs, td2, addr);
break;
case PT_GETFPREGS:
+ CTR2(KTR_PTRACE, "PT_GETFPREGS: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
error = PROC_READ(fpregs, td2, addr);
break;
case PT_SETDBREGS:
+ CTR2(KTR_PTRACE, "PT_SETDBREGS: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
td2->td_dbgflags |= TDB_USERWR;
error = PROC_WRITE(dbregs, td2, addr);
break;
case PT_GETDBREGS:
+ CTR2(KTR_PTRACE, "PT_GETDBREGS: tid %d (pid %d)", td2->td_tid,
+ p->p_pid);
error = PROC_READ(dbregs, td2, addr);
break;
@@ -1145,13 +1207,21 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
if (wrap32)
ptrace_lwpinfo_to32(pl, pl32);
#endif
+ CTR5(KTR_PTRACE,
+ "PT_LWPINFO: tid %d (pid %d) event %d flags %#x child pid %d",
+ td2->td_tid, p->p_pid, pl->pl_event, pl->pl_flags,
+ pl->pl_child_pid);
break;
case PT_GETNUMLWPS:
+ CTR2(KTR_PTRACE, "PT_GETNUMLWPS: pid %d: %d threads", p->p_pid,
+ p->p_numthreads);
td->td_retval[0] = p->p_numthreads;
break;
case PT_GETLWPLIST:
+ CTR3(KTR_PTRACE, "PT_GETLWPLIST: pid %d: data %d, actual %d",
+ p->p_pid, data, p->p_numthreads);
if (data <= 0) {
error = EINVAL;
break;
@@ -1175,6 +1245,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
break;
case PT_VM_TIMESTAMP:
+ CTR2(KTR_PTRACE, "PT_VM_TIMESTAMP: pid %d: timestamp %d",
+ p->p_pid, p->p_vmspace->vm_map.timestamp);
td->td_retval[0] = p->p_vmspace->vm_map.timestamp;
break;
@@ -1225,6 +1297,8 @@ stopevent(struct proc *p, unsigned int event, unsigned int val)
PROC_LOCK_ASSERT(p, MA_OWNED);
p->p_step = 1;
+ CTR3(KTR_PTRACE, "stopevent: pid %d event %u val %u", p->p_pid, event,
+ val);
do {
p->p_xstat = val;
p->p_xthread = NULL;
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 3240a5fe7ddd..3eb126bef8d4 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -382,7 +382,7 @@ kern_shmat_locked(struct thread *td, int shmid, const void *shmaddr,
*/
PROC_LOCK(p);
attach_va = round_page((vm_offset_t)p->p_vmspace->vm_daddr +
- lim_max(p, RLIMIT_DATA));
+ lim_max_proc(p, RLIMIT_DATA));
PROC_UNLOCK(p);
}
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index 2d1e8fecdf50..fcc9c47da35b 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -741,7 +741,7 @@ pts_alloc(int fflags, struct thread *td, struct file *fp)
PROC_UNLOCK(p);
return (EAGAIN);
}
- ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(p, RLIMIT_NPTS));
+ ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_NPTS));
if (!ok) {
racct_sub(p, RACCT_NPTS, 1);
PROC_UNLOCK(p);
@@ -795,7 +795,7 @@ pts_alloc_external(int fflags, struct thread *td, struct file *fp,
PROC_UNLOCK(p);
return (EAGAIN);
}
- ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(p, RLIMIT_NPTS));
+ ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_NPTS));
if (!ok) {
racct_sub(p, RACCT_NPTS, 1);
PROC_UNLOCK(p);
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
index 93c7ed1cdcce..fb8433027b81 100644
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -127,6 +127,7 @@ static fo_chmod_t shm_chmod;
static fo_chown_t shm_chown;
static fo_seek_t shm_seek;
static fo_fill_kinfo_t shm_fill_kinfo;
+static fo_mmap_t shm_mmap;
/* File descriptor operations. */
static struct fileops shm_ops = {
@@ -143,6 +144,7 @@ static struct fileops shm_ops = {
.fo_sendfile = vn_sendfile,
.fo_seek = shm_seek,
.fo_fill_kinfo = shm_fill_kinfo,
+ .fo_mmap = shm_mmap,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
@@ -187,14 +189,6 @@ uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio)
if (m->valid != VM_PAGE_BITS_ALL) {
if (vm_pager_has_page(obj, idx, NULL, NULL)) {
rv = vm_pager_get_pages(obj, &m, 1, 0);
- m = vm_page_lookup(obj, idx);
- if (m == NULL) {
- printf(
- "uiomove_object: vm_obj %p idx %jd null lookup rv %d\n",
- obj, idx, rv);
- VM_OBJECT_WUNLOCK(obj);
- return (EIO);
- }
if (rv != VM_PAGER_OK) {
printf(
"uiomove_object: vm_obj %p idx %jd valid %x pager error %d\n",
@@ -421,7 +415,7 @@ static int
shm_dotruncate(struct shmfd *shmfd, off_t length)
{
vm_object_t object;
- vm_page_t m, ma[1];
+ vm_page_t m;
vm_pindex_t idx, nobjsize;
vm_ooffset_t delta;
int base, rv;
@@ -463,12 +457,10 @@ retry:
VM_WAIT;
VM_OBJECT_WLOCK(object);
goto retry;
- } else if (m->valid != VM_PAGE_BITS_ALL) {
- ma[0] = m;
- rv = vm_pager_get_pages(object, ma, 1,
+ } else if (m->valid != VM_PAGE_BITS_ALL)
+ rv = vm_pager_get_pages(object, &m, 1,
0);
- m = vm_page_lookup(object, idx);
- } else
+ else
/* A cached page was reactivated. */
rv = VM_PAGER_OK;
vm_page_lock(m);
@@ -851,15 +843,37 @@ sys_shm_unlink(struct thread *td, struct shm_unlink_args *uap)
return (error);
}
-/*
- * mmap() helper to validate mmap() requests against shm object state
- * and give mmap() the vm_object to use for the mapping.
- */
int
-shm_mmap(struct shmfd *shmfd, vm_size_t objsize, vm_ooffset_t foff,
- vm_object_t *obj)
+shm_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t objsize,
+ vm_prot_t prot, vm_prot_t cap_maxprot, int flags,
+ vm_ooffset_t foff, struct thread *td)
{
+ struct shmfd *shmfd;
+ vm_prot_t maxprot;
+ int error;
+
+ shmfd = fp->f_data;
+ maxprot = VM_PROT_NONE;
+ /* FREAD should always be set. */
+ if ((fp->f_flag & FREAD) != 0)
+ maxprot |= VM_PROT_EXECUTE | VM_PROT_READ;
+ if ((fp->f_flag & FWRITE) != 0)
+ maxprot |= VM_PROT_WRITE;
+
+ /* Don't permit shared writable mappings on read-only descriptors. */
+ if ((flags & MAP_SHARED) != 0 &&
+ (maxprot & VM_PROT_WRITE) == 0 &&
+ (prot & VM_PROT_WRITE) != 0)
+ return (EACCES);
+ maxprot &= cap_maxprot;
+
+#ifdef MAC
+ error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, flags);
+ if (error != 0)
+ return (error);
+#endif
+
/*
* XXXRW: This validation is probably insufficient, and subject to
* sign errors. It should be fixed.
@@ -872,7 +886,11 @@ shm_mmap(struct shmfd *shmfd, vm_size_t objsize, vm_ooffset_t foff,
vfs_timestamp(&shmfd->shm_atime);
mtx_unlock(&shm_timestamp_lock);
vm_object_reference(shmfd->shm_object);
- *obj = shmfd->shm_object;
+
+ error = vm_mmap_object(map, addr, objsize, prot, maxprot, flags,
+ shmfd->shm_object, foff, FALSE, td);
+ if (error != 0)
+ vm_object_deallocate(shmfd->shm_object);
return (0);
}
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 88952ed6629a..243450d0d638 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -420,9 +420,7 @@ sbreserve_locked(struct sockbuf *sb, u_long cc, struct socket *so,
if (cc > sb_max_adj)
return (0);
if (td != NULL) {
- PROC_LOCK(td->td_proc);
- sbsize_limit = lim_cur(td->td_proc, RLIMIT_SBSIZE);
- PROC_UNLOCK(td->td_proc);
+ sbsize_limit = lim_cur(td, RLIMIT_SBSIZE);
} else
sbsize_limit = RLIM_INFINITY;
if (!chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, cc,
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 1efe3da8a8d4..e3557ba72604 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -2026,10 +2026,7 @@ sendfile_readpage(vm_object_t obj, struct vnode *vp, int nd,
if (vm_pager_has_page(obj, pindex, NULL, NULL)) {
rv = vm_pager_get_pages(obj, &m, 1, 0);
SFSTAT_INC(sf_iocnt);
- m = vm_page_lookup(obj, pindex);
- if (m == NULL)
- error = EIO;
- else if (rv != VM_PAGER_OK) {
+ if (rv != VM_PAGER_OK) {
vm_page_lock(m);
vm_page_free(m);
vm_page_unlock(m);
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index ef0b83c9b53c..808020e5e61d 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1787,7 +1787,7 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp, int flags)
fdp = (int *)
CMSG_DATA(mtod(*controlp, struct cmsghdr *));
if (fdallocn(td, 0, fdp, newfds) != 0) {
- FILEDESC_XUNLOCK(td->td_proc->p_fd);
+ FILEDESC_XUNLOCK(fdesc);
error = EMSGSIZE;
unp_freerights(fdep, newfds);
m_freem(*controlp);
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index 960108253e72..362ebb7ba671 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -310,7 +310,6 @@ static struct buf *
cluster_rbuild(struct vnode *vp, u_quad_t filesize, daddr_t lbn,
daddr_t blkno, long size, int run, int gbflags, struct buf *fbp)
{
- struct bufobj *bo;
struct buf *bp, *tbp;
daddr_t bn;
off_t off;
@@ -376,7 +375,6 @@ cluster_rbuild(struct vnode *vp, u_quad_t filesize, daddr_t lbn,
bp->b_npages = 0;
inc = btodb(size);
- bo = &vp->v_bufobj;
for (bn = blkno, i = 0; i < run; ++i, bn += inc) {
if (i == 0) {
VM_OBJECT_WLOCK(tbp->b_bufobj->bo_object);
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c
index cf3928ee91e4..f935954fcef2 100644
--- a/sys/kern/vfs_init.c
+++ b/sys/kern/vfs_init.c
@@ -311,9 +311,7 @@ static int
vfs_unregister(struct vfsconf *vfc)
{
struct vfsconf *vfsp;
- int error, i, maxtypenum;
-
- i = vfc->vfc_typenum;
+ int error, maxtypenum;
vfsconf_lock();
vfsp = vfs_byname_locked(vfc->vfc_name);
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 09fa7ed071bf..c86259b11637 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1128,12 +1128,7 @@ struct unmount_args {
#endif
/* ARGSUSED */
int
-sys_unmount(td, uap)
- struct thread *td;
- register struct unmount_args /* {
- char *path;
- int flags;
- } */ *uap;
+sys_unmount(struct thread *td, struct unmount_args *uap)
{
struct nameidata nd;
struct mount *mp;
@@ -1164,8 +1159,10 @@ sys_unmount(td, uap)
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
if (mp->mnt_stat.f_fsid.val[0] == id0 &&
- mp->mnt_stat.f_fsid.val[1] == id1)
+ mp->mnt_stat.f_fsid.val[1] == id1) {
+ vfs_ref(mp);
break;
+ }
}
mtx_unlock(&mountlist_mtx);
} else {
@@ -1183,8 +1180,10 @@ sys_unmount(td, uap)
}
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
- if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0)
+ if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0) {
+ vfs_ref(mp);
break;
+ }
}
mtx_unlock(&mountlist_mtx);
}
@@ -1202,8 +1201,10 @@ sys_unmount(td, uap)
/*
* Don't allow unmounting the root filesystem.
*/
- if (mp->mnt_flag & MNT_ROOTFS)
+ if (mp->mnt_flag & MNT_ROOTFS) {
+ vfs_rel(mp);
return (EINVAL);
+ }
error = dounmount(mp, uap->flags, td);
return (error);
}
@@ -1212,10 +1213,7 @@ sys_unmount(td, uap)
* Do the actual filesystem unmount.
*/
int
-dounmount(mp, flags, td)
- struct mount *mp;
- int flags;
- struct thread *td;
+dounmount(struct mount *mp, int flags, struct thread *td)
{
struct vnode *coveredvp, *fsrootvp;
int error;
@@ -1235,6 +1233,7 @@ dounmount(mp, flags, td)
if (coveredvp->v_mountedhere != mp ||
coveredvp->v_mountedhere->mnt_gen != mnt_gen_r) {
VOP_UNLOCK(coveredvp, 0);
+ vfs_rel(mp);
return (EBUSY);
}
}
@@ -1243,13 +1242,14 @@ dounmount(mp, flags, td)
* original mount is permitted to unmount this filesystem.
*/
error = vfs_suser(mp, td);
- if (error) {
+ if (error != 0) {
if (coveredvp)
VOP_UNLOCK(coveredvp, 0);
+ vfs_rel(mp);
return (error);
}
- vn_start_write(NULL, &mp, V_WAIT);
+ vn_start_write(NULL, &mp, V_WAIT | V_MNTREF);
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 ||
!TAILQ_EMPTY(&mp->mnt_uppers)) {
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 8e34456621ca..625d193b2c1b 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -3502,8 +3502,9 @@ vfs_unmountall(void)
*/
while(!TAILQ_EMPTY(&mountlist)) {
mp = TAILQ_LAST(&mountlist, mntlist);
+ vfs_ref(mp);
error = dounmount(mp, MNT_FORCE, td);
- if (error) {
+ if (error != 0) {
TAILQ_REMOVE(&mountlist, mp, mnt_list);
/*
* XXX: Due to the way in which we mount the root
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 01d448edf698..0b073b9cf110 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/limits.h>
#include <sys/lock.h>
+#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
@@ -80,6 +81,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_map.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
+#include <vm/vnode_pager.h>
static fo_rdwr_t vn_read;
static fo_rdwr_t vn_write;
@@ -90,6 +92,7 @@ static fo_poll_t vn_poll;
static fo_kqfilter_t vn_kqfilter;
static fo_stat_t vn_statfile;
static fo_close_t vn_closefile;
+static fo_mmap_t vn_mmap;
struct fileops vnops = {
.fo_read = vn_io_fault,
@@ -105,6 +108,7 @@ struct fileops vnops = {
.fo_sendfile = vn_sendfile,
.fo_seek = vn_seek,
.fo_fill_kinfo = vn_fill_kinfo,
+ .fo_mmap = vn_mmap,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
@@ -1646,16 +1650,18 @@ unlock:
}
int
-vn_start_write(vp, mpp, flags)
- struct vnode *vp;
- struct mount **mpp;
- int flags;
+vn_start_write(struct vnode *vp, struct mount **mpp, int flags)
{
struct mount *mp;
int error;
- if (!vn_suspendable(vp, mpp))
+ KASSERT((flags & V_MNTREF) == 0 || (*mpp != NULL && vp == NULL),
+ ("V_MNTREF requires mp"));
+ if (!vn_suspendable(vp, mpp)) {
+ if ((flags & V_MNTREF) != 0)
+ vfs_rel(*mpp);
return (0);
+ }
error = 0;
/*
@@ -1681,7 +1687,7 @@ vn_start_write(vp, mpp, flags)
* emulate a vfs_ref().
*/
MNT_ILOCK(mp);
- if (vp == NULL)
+ if (vp == NULL && (flags & V_MNTREF) == 0)
MNT_REF(mp);
return (vn_start_write_locked(mp, flags));
@@ -1695,16 +1701,18 @@ vn_start_write(vp, mpp, flags)
* time, these operations are halted until the suspension is over.
*/
int
-vn_start_secondary_write(vp, mpp, flags)
- struct vnode *vp;
- struct mount **mpp;
- int flags;
+vn_start_secondary_write(struct vnode *vp, struct mount **mpp, int flags)
{
struct mount *mp;
int error;
- if (!vn_suspendable(vp, mpp))
+ KASSERT((flags & V_MNTREF) == 0 || (*mpp != NULL && vp == NULL),
+ ("V_MNTREF requires mp"));
+ if (!vn_suspendable(vp, mpp)) {
+ if ((flags & V_MNTREF) != 0)
+ vfs_rel(*mpp);
return (0);
+ }
retry:
if (vp != NULL) {
@@ -1730,7 +1738,7 @@ vn_start_secondary_write(vp, mpp, flags)
* emulate a vfs_ref().
*/
MNT_ILOCK(mp);
- if (vp == NULL)
+ if (vp == NULL && (flags & V_MNTREF) == 0)
MNT_REF(mp);
if ((mp->mnt_kern_flag & (MNTK_SUSPENDED | MNTK_SUSPEND2)) == 0) {
mp->mnt_secondary_writes++;
@@ -2098,19 +2106,18 @@ vn_vget_ino_gen(struct vnode *vp, vn_get_ino_t alloc, void *alloc_arg,
int
vn_rlimit_fsize(const struct vnode *vp, const struct uio *uio,
- const struct thread *td)
+ struct thread *td)
{
if (vp->v_type != VREG || td == NULL)
return (0);
- PROC_LOCK(td->td_proc);
if ((uoff_t)uio->uio_offset + uio->uio_resid >
- lim_cur(td->td_proc, RLIMIT_FSIZE)) {
+ lim_cur(td, RLIMIT_FSIZE)) {
+ PROC_LOCK(td->td_proc);
kern_psignal(td->td_proc, SIGXFSZ);
PROC_UNLOCK(td->td_proc);
return (EFBIG);
}
- PROC_UNLOCK(td->td_proc);
return (0);
}
@@ -2358,3 +2365,95 @@ vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif)
kif->kf_un.kf_file.kf_file_rdev = va.va_rdev;
return (0);
}
+
+int
+vn_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
+ vm_prot_t prot, vm_prot_t cap_maxprot, int flags, vm_ooffset_t foff,
+ struct thread *td)
+{
+#ifdef HWPMC_HOOKS
+ struct pmckern_map_in pkm;
+#endif
+ struct mount *mp;
+ struct vnode *vp;
+ vm_object_t object;
+ vm_prot_t maxprot;
+ boolean_t writecounted;
+ int error;
+
+#if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \
+ defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4)
+ /*
+ * POSIX shared-memory objects are defined to have
+ * kernel persistence, and are not defined to support
+ * read(2)/write(2) -- or even open(2). Thus, we can
+ * use MAP_ASYNC to trade on-disk coherence for speed.
+ * The shm_open(3) library routine turns on the FPOSIXSHM
+ * flag to request this behavior.
+ */
+ if ((fp->f_flag & FPOSIXSHM) != 0)
+ flags |= MAP_NOSYNC;
+#endif
+ vp = fp->f_vnode;
+
+ /*
+ * Ensure that file and memory protections are
+ * compatible. Note that we only worry about
+ * writability if mapping is shared; in this case,
+ * current and max prot are dictated by the open file.
+ * XXX use the vnode instead? Problem is: what
+ * credentials do we use for determination? What if
+ * proc does a setuid?
+ */
+ mp = vp->v_mount;
+ if (mp != NULL && (mp->mnt_flag & MNT_NOEXEC) != 0)
+ maxprot = VM_PROT_NONE;
+ else
+ maxprot = VM_PROT_EXECUTE;
+ if ((fp->f_flag & FREAD) != 0)
+ maxprot |= VM_PROT_READ;
+ else if ((prot & VM_PROT_READ) != 0)
+ return (EACCES);
+
+ /*
+ * If we are sharing potential changes via MAP_SHARED and we
+ * are trying to get write permission although we opened it
+ * without asking for it, bail out.
+ */
+ if ((flags & MAP_SHARED) != 0) {
+ if ((fp->f_flag & FWRITE) != 0)
+ maxprot |= VM_PROT_WRITE;
+ else if ((prot & VM_PROT_WRITE) != 0)
+ return (EACCES);
+ } else {
+ maxprot |= VM_PROT_WRITE;
+ cap_maxprot |= VM_PROT_WRITE;
+ }
+ maxprot &= cap_maxprot;
+
+ writecounted = FALSE;
+ error = vm_mmap_vnode(td, size, prot, &maxprot, &flags, vp,
+ &foff, &object, &writecounted);
+ if (error != 0)
+ return (error);
+ error = vm_mmap_object(map, addr, size, prot, maxprot, flags, object,
+ foff, writecounted, td);
+ if (error != 0) {
+ /*
+ * If this mapping was accounted for in the vnode's
+ * writecount, then undo that now.
+ */
+ if (writecounted)
+ vnode_pager_release_writecount(object, 0, size);
+ vm_object_deallocate(object);
+ }
+#ifdef HWPMC_HOOKS
+ /* Inform hwpmc(4) if an executable is being mapped. */
+ if (error == 0 && (prot & VM_PROT_EXECUTE) != 0) {
+ pkm.pm_file = vp;
+ pkm.pm_address = (uintptr_t) addr;
+ PMC_CALL_HOOK(td, PMC_FN_MMAP, (void *) &pkm);
+ }
+#endif
+ return (error);
+}
diff --git a/sys/libkern/arm/memcpy.S b/sys/libkern/arm/memcpy.S
index 9fca8f6cad86..3703195e11d3 100644
--- a/sys/libkern/arm/memcpy.S
+++ b/sys/libkern/arm/memcpy.S
@@ -31,7 +31,11 @@ __FBSDID("$FreeBSD$");
#ifdef __ARM_EABI__
ENTRY_NP(__aeabi_memcpy)
+EENTRY_NP(__aeabi_memcpy4)
+EENTRY_NP(__aeabi_memcpy8)
b memcpy
+EEND(__aeabi_memcpy8)
+EEND(__aeabi_memcpy4)
END(__aeabi_memcpy)
#endif
diff --git a/sys/mips/conf/AR71XX_BASE b/sys/mips/conf/AR71XX_BASE
index 357f9659c66b..d2ff804c22ed 100644
--- a/sys/mips/conf/AR71XX_BASE
+++ b/sys/mips/conf/AR71XX_BASE
@@ -26,6 +26,9 @@ makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
# modules already built.
makeoptions MODULES_OVERRIDE="random gpio ar71xx if_gif if_gre if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_pci"
+# For small memory footprints
+options VM_KMEM_SIZE_SCALE=1
+
options DDB
options KDB
diff --git a/sys/mips/conf/AR724X_BASE b/sys/mips/conf/AR724X_BASE
index f0be92c93995..7c2845038248 100644
--- a/sys/mips/conf/AR724X_BASE
+++ b/sys/mips/conf/AR724X_BASE
@@ -27,6 +27,9 @@ makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
# modules already built.
makeoptions MODULES_OVERRIDE="random gpio ar71xx if_gif if_gre if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_pci hwpmc cam"
+# For small memory footprints
+options VM_KMEM_SIZE_SCALE=1
+
options DDB
options KDB
diff --git a/sys/mips/conf/AR934X_BASE b/sys/mips/conf/AR934X_BASE
index 7a62633917f5..50af5f2f891d 100644
--- a/sys/mips/conf/AR934X_BASE
+++ b/sys/mips/conf/AR934X_BASE
@@ -20,7 +20,7 @@ files "../atheros/files.ar71xx"
hints "AR934X_BASE.hints"
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
-makeoptions MODULES_OVERRIDE="random gpio ar71xx if_gif if_gre if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_ahb hwpmc"
+makeoptions MODULES_OVERRIDE="random gpio ar71xx if_gif if_gre if_vlan if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_ahb hwpmc ipfw ipfw_nat libalias"
# makeoptions MODULES_OVERRIDE=""
options DDB
diff --git a/sys/mips/include/pcpu.h b/sys/mips/include/pcpu.h
index 89b65257cefd..f4be33dd8aa9 100644
--- a/sys/mips/include/pcpu.h
+++ b/sys/mips/include/pcpu.h
@@ -31,6 +31,7 @@
#ifndef _MACHINE_PCPU_H_
#define _MACHINE_PCPU_H_
+#include <machine/cpufunc.h>
#include <machine/pte.h>
#define PCPU_MD_COMMON_FIELDS \
diff --git a/sys/mips/include/vmparam.h b/sys/mips/include/vmparam.h
index 89caf27d296e..020d0ac0184f 100644
--- a/sys/mips/include/vmparam.h
+++ b/sys/mips/include/vmparam.h
@@ -149,13 +149,12 @@
#define VM_PHYSSEG_SPARSE
/*
- * Create three free page pools: VM_FREEPOOL_DEFAULT is the default pool
+ * Create two free page pools: VM_FREEPOOL_DEFAULT is the default pool
* from which physical pages are allocated and VM_FREEPOOL_DIRECT is
* the pool from which physical pages for small UMA objects are
* allocated.
*/
-#define VM_NFREEPOOL 3
-#define VM_FREEPOOL_CACHE 2
+#define VM_NFREEPOOL 2
#define VM_FREEPOOL_DEFAULT 0
#define VM_FREEPOOL_DIRECT 1
diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c
index d37471388ae5..8cbe8d3df6cc 100644
--- a/sys/mips/mips/elf_machdep.c
+++ b/sys/mips/mips/elf_machdep.c
@@ -83,6 +83,7 @@ struct sysentvec elf64_freebsd_sysvec = {
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
static Elf64_Brandinfo freebsd_brand_info = {
@@ -139,6 +140,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
static Elf32_Brandinfo freebsd_brand_info = {
diff --git a/sys/mips/mips/freebsd32_machdep.c b/sys/mips/mips/freebsd32_machdep.c
index 9de4685bac8b..530342003d61 100644
--- a/sys/mips/mips/freebsd32_machdep.c
+++ b/sys/mips/mips/freebsd32_machdep.c
@@ -106,6 +106,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = freebsd32_syscallnames,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
@@ -418,12 +419,6 @@ freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sfp = (struct sigframe32 *)((vm_offset_t)(td->td_frame->sp -
sizeof(struct sigframe32)) & ~(sizeof(__int64_t) - 1));
- /* Translate the signal if appropriate */
- if (p->p_sysent->sv_sigtbl) {
- if (sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
- }
-
/* Build the argument list for the signal handler. */
td->td_frame->a0 = sig;
td->td_frame->a2 = (register_t)(intptr_t)&sfp->sf_uc;
diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c
index 8f55280f2b73..d5f6df0641f4 100644
--- a/sys/mips/mips/pm_machdep.c
+++ b/sys/mips/mips/pm_machdep.c
@@ -133,12 +133,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sfp = (struct sigframe *)((vm_offset_t)(regs->sp -
sizeof(struct sigframe)) & ~(sizeof(__int64_t) - 1));
- /* Translate the signal if appropriate */
- if (p->p_sysent->sv_sigtbl) {
- if (sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
- }
-
/* Build the argument list for the signal handler. */
regs->a0 = sig;
regs->a2 = (register_t)(intptr_t)&sfp->sf_uc;
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 7afc5a89012d..39b8bfd384e3 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -196,6 +196,8 @@ SUBDIR= \
${_linprocfs} \
${_linsysfs} \
${_linux} \
+ ${_linux_common} \
+ ${_linux64} \
${_linuxapi} \
lmc \
lpt \
@@ -510,7 +512,6 @@ _io= io
.if ${MK_OFED} != "no" || defined(ALL_MODULES)
_ipoib= ipoib
.endif
-_ix= ix
_ixv= ixv
_linprocfs= linprocfs
_linsysfs= linsysfs
@@ -619,6 +620,8 @@ _x86bios= x86bios
.if ${MACHINE_CPUARCH} == "amd64"
_ixl= ixl
_ixlv= ixlv
+_linux64= linux64
+_linux_common= linux_common
_ntb= ntb
_qlxge= qlxge
_qlxgb= qlxgb
diff --git a/sys/modules/em/Makefile b/sys/modules/em/Makefile
index 3112d010a372..1de7c62298e9 100644
--- a/sys/modules/em/Makefile
+++ b/sys/modules/em/Makefile
@@ -2,7 +2,8 @@
.PATH: ${.CURDIR}/../../dev/e1000
KMOD = if_em
-SRCS = device_if.h bus_if.h pci_if.h opt_inet.h opt_inet6.h
+SRCS = device_if.h bus_if.h pci_if.h opt_ddb.h opt_em.h opt_inet.h \
+ opt_inet6.h
SRCS += $(CORE_SRC) $(LEGACY_SRC)
SRCS += $(COMMON_SHARED) $(LEGACY_SHARED) $(PCIE_SHARED)
CORE_SRC = if_em.c e1000_osdep.c
diff --git a/sys/modules/geom/geom_map/Makefile b/sys/modules/geom/geom_map/Makefile
new file mode 100644
index 000000000000..6b26ba9470fe
--- /dev/null
+++ b/sys/modules/geom/geom_map/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../geom
+
+KMOD= geom_map
+SRCS= geom_map.c bus_if.h device_if.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/i2c/controllers/Makefile b/sys/modules/i2c/controllers/Makefile
index 2b4432fef109..132ff2d3babe 100644
--- a/sys/modules/i2c/controllers/Makefile
+++ b/sys/modules/i2c/controllers/Makefile
@@ -3,7 +3,7 @@
.if ${MACHINE} == "pc98"
SUBDIR = lpbb
.else
-SUBDIR = alpm amdpm amdsmb ichsmb intpm ismt nfsmb viapm lpbb pcf
+SUBDIR = alpm amdpm amdsmb ichiic ichsmb intpm ismt nfsmb viapm lpbb pcf
.endif
.include <bsd.subdir.mk>
diff --git a/sys/modules/i2c/controllers/ichiic/Makefile b/sys/modules/i2c/controllers/ichiic/Makefile
new file mode 100644
index 000000000000..288a79e450bd
--- /dev/null
+++ b/sys/modules/i2c/controllers/ichiic/Makefile
@@ -0,0 +1,8 @@
+#$FreeBSD$
+
+.PATH: ${.CURDIR}/../../../../dev/ichiic
+KMOD = ig4
+SRCS = device_if.h bus_if.h iicbb_if.h pci_if.h smbus_if.h \
+ ig4_iic.c ig4_pci.c ig4_reg.h ig4_var.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/ixl/Makefile b/sys/modules/ixl/Makefile
index 7d2fca994d0b..2f969a5a497f 100755..100644
--- a/sys/modules/ixl/Makefile
+++ b/sys/modules/ixl/Makefile
@@ -3,14 +3,14 @@
.PATH: ${.CURDIR}/../../dev/ixl
KMOD = if_ixl
-SRCS = device_if.h bus_if.h pci_if.h opt_bdg.h
+SRCS = device_if.h bus_if.h pci_if.h pci_iov_if.h opt_bdg.h
SRCS += opt_inet.h opt_inet6.h opt_rss.h
SRCS += if_ixl.c ixl_txrx.c i40e_osdep.c
# Shared source
SRCS += i40e_common.c i40e_nvm.c i40e_adminq.c i40e_lan_hmc.c i40e_hmc.c
-CFLAGS += -DSMP
+CFLAGS += -DSMP -DIXL_DEBUG_SYSCTL
# Add Flow Director support
# CFLAGS += -DIXL_FDIR
diff --git a/sys/modules/ixlv/Makefile b/sys/modules/ixlv/Makefile
index 2e51bb8b28e7..3e2678e9a3fd 100755
--- a/sys/modules/ixlv/Makefile
+++ b/sys/modules/ixlv/Makefile
@@ -8,7 +8,7 @@ SRCS += opt_inet.h opt_inet6.h opt_rss.h
SRCS += if_ixlv.c ixlvc.c ixl_txrx.c i40e_osdep.c
# Shared source
-SRCS += i40e_common.c i40e_nvm.c i40e_adminq.c i40e_lan_hmc.c i40e_hmc.c
+SRCS += i40e_common.c i40e_nvm.c i40e_adminq.c
CFLAGS += -DSMP
diff --git a/sys/modules/ixv/Makefile b/sys/modules/ixv/Makefile
index f8ce347d3128..32077392152d 100644
--- a/sys/modules/ixv/Makefile
+++ b/sys/modules/ixv/Makefile
@@ -7,9 +7,8 @@ SRCS = device_if.h bus_if.h pci_if.h
SRCS += opt_inet.h opt_inet6.h opt_rss.h
SRCS += if_ixv.c ix_txrx.c
# Shared source
-SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c ixgbe_mbx.c ixgbe_vf.c
-SRCS += ixgbe_dcb.c ixgbe_dcb_82598.c ixgbe_dcb_82599.c
-SRCS += ixgbe_82598.c ixgbe_82599.c ixgbe_x540.c ixgbe_x550.c
+SRCS += ixgbe_common.c ixgbe_api.c ixgbe_phy.c
+SRCS += ixgbe_dcb.c ixgbe_mbx.c ixgbe_vf.c
CFLAGS+= -I${.CURDIR}/../../dev/ixgbe -DSMP
.include <bsd.kmod.mk>
diff --git a/sys/modules/linprocfs/Makefile b/sys/modules/linprocfs/Makefile
index 4b1b37543031..979429fd2ae1 100644
--- a/sys/modules/linprocfs/Makefile
+++ b/sys/modules/linprocfs/Makefile
@@ -5,11 +5,6 @@
KMOD= linprocfs
SRCS= vnode_if.h \
device_if.h bus_if.h \
- linprocfs.c \
- opt_compat.h
-
-.if ${MACHINE_CPUARCH} == "amd64"
-CFLAGS+=-DCOMPAT_LINUX32
-.endif
+ linprocfs.c
.include <bsd.kmod.mk>
diff --git a/sys/modules/linsysfs/Makefile b/sys/modules/linsysfs/Makefile
index 401796779205..13230ff5e8ea 100644
--- a/sys/modules/linsysfs/Makefile
+++ b/sys/modules/linsysfs/Makefile
@@ -5,11 +5,6 @@
KMOD= linsysfs
SRCS= vnode_if.h \
device_if.h bus_if.h pci_if.h \
- linsysfs.c \
- opt_compat.h
-
-.if ${MACHINE_CPUARCH} == "amd64"
-CFLAGS+=-DCOMPAT_LINUX32
-.endif
+ linsysfs.c
.include <bsd.kmod.mk>
diff --git a/sys/modules/linux/Makefile b/sys/modules/linux/Makefile
index a671a3377853..e887290260e5 100644
--- a/sys/modules/linux/Makefile
+++ b/sys/modules/linux/Makefile
@@ -7,16 +7,18 @@ CFLAGS+=-DCOMPAT_FREEBSD32 -DCOMPAT_LINUX32
.PATH: ${.CURDIR}/../../compat/linux ${.CURDIR}/../../${MACHINE_CPUARCH}/linux${SFX}
+VDSO= linux${SFX}_vdso
+
KMOD= linux
-SRCS= linux_fork.c linux${SFX}_dummy.c linux_emul.c linux_file.c \
+SRCS= linux_fork.c linux${SFX}_dummy.c linux_file.c linux_event.c \
linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \
- linux${SFX}_machdep.c linux_mib.c linux_misc.c linux_signal.c \
+ linux${SFX}_machdep.c linux_misc.c linux_signal.c \
linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c \
- linux${SFX}_sysvec.c linux_uid16.c linux_util.c linux_time.c \
- linux_timer.c \
+ linux${SFX}_sysvec.c linux_uid16.c linux_time.c \
+ linux_timer.c linux_vdso.c \
opt_inet6.h opt_compat.h opt_posix.h opt_usb.h vnode_if.h \
device_if.h bus_if.h assym.s \
- linux${SFX}_locore.s linux${SFX}_support.s
+ linux${SFX}_support.s
DPSRCS= linux${SFX}_genassym.c
# XXX: for assym.s
@@ -25,31 +27,49 @@ SRCS+= opt_kstack_pages.h opt_nfs.h opt_compat.h opt_hwpmc_hooks.h
SRCS+= opt_apic.h
.endif
+OBJS= ${VDSO}.so
+
.if ${MACHINE_CPUARCH} == "i386"
-SRCS+= linux_ptrace.c imgact_linux.c opt_cpu.h
+SRCS+= linux_ptrace.c imgact_linux.c linux_util.c linux_mib.c \
+ linux_emul.c opt_cpu.h linux.c
.endif
+.if ${MACHINE_CPUARCH} == "i386"
EXPORT_SYMS=
EXPORT_SYMS+= linux_emul_path
EXPORT_SYMS+= linux_get_osname
EXPORT_SYMS+= linux_get_osrelease
-EXPORT_SYMS+= linux_ifname
EXPORT_SYMS+= linux_ioctl_register_handler
EXPORT_SYMS+= linux_ioctl_unregister_handler
+.endif
-CLEANFILES= linux${SFX}_assym.h linux${SFX}_genassym.o
+CLEANFILES= linux${SFX}_assym.h linux${SFX}_genassym.o linux${SFX}_locore.o
linux${SFX}_assym.h: linux${SFX}_genassym.o
sh ${SYSDIR}/kern/genassym.sh linux${SFX}_genassym.o > ${.TARGET}
linux${SFX}_locore.o: linux${SFX}_assym.h assym.s
- ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
+ ${CC} -x assembler-with-cpp -DLOCORE -m32 -shared -s \
+ -pipe -I. -I${SYSDIR} -Werror -Wall -fno-common -nostdinc -nostdlib \
+ -fno-omit-frame-pointer \
+ -Wl,-T${.CURDIR}/../../${MACHINE_CPUARCH}/linux${SFX}/${VDSO}.lds.s \
+ -Wl,-soname=${VDSO}.so.1,--eh-frame-hdr,-fPIC,-warn-common \
${.IMPSRC} -o ${.TARGET}
linux${SFX}_support.o: linux${SFX}_assym.h assym.s
${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
${.IMPSRC} -o ${.TARGET}
+.if ${MACHINE_CPUARCH} == "amd64"
+${VDSO}.so: linux${SFX}_locore.o
+ ${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \
+ --binary-architecture i386 linux${SFX}_locore.o ${.TARGET}
+.else
+${VDSO}.so: linux${SFX}_locore.o
+ ${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd \
+ --binary-architecture i386 linux${SFX}_locore.o ${.TARGET}
+.endif
+
linux${SFX}_genassym.o:
${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC}
@@ -57,6 +77,9 @@ linux${SFX}_genassym.o:
.if defined(KTR)
CFLAGS+= -DKTR
.endif
+.if defined(DEBUG)
+CFLAGS+= -DDEBUG
+.endif
.endif
.include <bsd.kmod.mk>
diff --git a/sys/modules/linux64/Makefile b/sys/modules/linux64/Makefile
new file mode 100644
index 000000000000..165632350d42
--- /dev/null
+++ b/sys/modules/linux64/Makefile
@@ -0,0 +1,55 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../compat/linux ${.CURDIR}/../../${MACHINE_ARCH}/linux
+
+VDSO= linux_vdso
+
+KMOD= linux64
+SRCS= linux_fork.c linux_dummy.c linux_file.c linux_event.c \
+ linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \
+ linux_machdep.c linux_misc.c linux_signal.c \
+ linux_socket.c linux_stats.c linux_sysctl.c linux_sysent.c \
+ linux_sysvec.c linux_time.c linux_vdso.c linux_timer.c \
+ opt_inet6.h opt_compat.h opt_kdtrace.h opt_posix.h opt_usb.h \
+ vnode_if.h device_if.h bus_if.h assym.s \
+ linux_support.s
+DPSRCS= linux_genassym.c
+
+# XXX: for assym.s
+SRCS+= opt_kstack_pages.h opt_nfs.h opt_apic.h opt_hwpmc_hooks.h
+
+CLEANFILES= linux_assym.h linux_genassym.o linux_locore.o
+
+OBJS= ${VDSO}.so
+
+linux_assym.h: linux_genassym.o
+ sh ${SYSDIR}/kern/genassym.sh linux_genassym.o > ${.TARGET}
+
+linux_locore.o: linux_locore.s linux_assym.h
+ ${CC} -x assembler-with-cpp -DLOCORE -shared -mcmodel=small \
+ -pipe -I. -I${SYSDIR} -Werror -Wall -fno-common -nostdinc \
+ -Wl,-T${.CURDIR}/../../${MACHINE_CPUARCH}/linux/${VDSO}.lds.s \
+ -Wl,-soname=${VDSO}.so.1,-fPIC,-warn-common -nostdlib \
+ ${.IMPSRC} -o ${.TARGET}
+
+${VDSO}.so: linux_locore.o
+ ${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \
+ -S -g --binary-architecture i386:x86-64 linux_locore.o ${.TARGET}
+
+linux_support.o: assym.s linux_assym.h
+ ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \
+ ${.IMPSRC} -o ${.TARGET}
+
+linux_genassym.o:
+ ${CC} -c ${CFLAGS:N-fno-common} ${.IMPSRC}
+
+.if !defined(KERNBUILDDIR)
+.if defined(DEBUG)
+CFLAGS+=-DDEBUG
+.endif
+.if defined(KTR)
+CFLAGS+=-DKTR
+.endif
+.endif
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/linux_common/Makefile b/sys/modules/linux_common/Makefile
new file mode 100644
index 000000000000..91449f774ef5
--- /dev/null
+++ b/sys/modules/linux_common/Makefile
@@ -0,0 +1,25 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../compat/linux
+
+KMOD= linux_common
+SRCS= linux_common.c linux_mib.c linux_util.c linux_emul.c \
+ linux.c opt_compat.h device_if.h vnode_if.h bus_if.h
+
+EXPORT_SYMS=
+EXPORT_SYMS+= linux_emul_path
+EXPORT_SYMS+= linux_ioctl_register_handler
+EXPORT_SYMS+= linux_ioctl_unregister_handler
+EXPORT_SYMS+= linux_get_osname
+EXPORT_SYMS+= linux_get_osrelease
+
+.if !defined(KERNBUILDDIR)
+.if defined(DEBUG)
+CFLAGS+=-DDEBUG
+.endif
+.if defined(KTR)
+CFLAGS+=-DKTR
+.endif
+.endif
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/proto/Makefile b/sys/modules/proto/Makefile
index 4cfbd72a0bdf..3038c77f2f21 100644
--- a/sys/modules/proto/Makefile
+++ b/sys/modules/proto/Makefile
@@ -5,6 +5,7 @@
KMOD= proto
SRCS= \
proto_bus_pci.c \
+ proto_busdma.c \
proto_core.c
SRCS+= \
diff --git a/sys/modules/pseudofs/Makefile b/sys/modules/pseudofs/Makefile
index d5696c5c4795..6ddb74929f94 100644
--- a/sys/modules/pseudofs/Makefile
+++ b/sys/modules/pseudofs/Makefile
@@ -23,4 +23,10 @@ EXPORT_SYMS= pfs_mount \
pfs_enable \
pfs_destroy
+.if !defined(KERNBUILDDIR)
+.if defined(PSEUDOFS_TRACE)
+CFLAGS+=-DPSEUDOFS_TRACE
+.endif
+.endif
+
.include <bsd.kmod.mk>
diff --git a/sys/modules/sfxge/Makefile b/sys/modules/sfxge/Makefile
index 48a2983d4b34..b2116d8e7e97 100644
--- a/sys/modules/sfxge/Makefile
+++ b/sys/modules/sfxge/Makefile
@@ -9,22 +9,32 @@ SRCS+= opt_inet.h opt_inet6.h opt_sched.h
.PATH: ${.CURDIR}/../../dev/sfxge
SRCS+= sfxge.c sfxge_dma.c sfxge_ev.c
-SRCS+= sfxge_intr.c sfxge_mcdi.c
+SRCS+= sfxge_intr.c sfxge_mcdi.c sfxge_nvram.c
SRCS+= sfxge_port.c sfxge_rx.c sfxge_tx.c
SRCS+= sfxge.h sfxge_rx.h sfxge_tx.h sfxge_version.h
.PATH: ${.CURDIR}/../../dev/sfxge/common
-SRCS+= efx_ev.c efx_intr.c efx_mac.c efx_mcdi.c efx_nic.c
+SRCS+= efx_bootcfg.c efx_crc32.c efx_ev.c efx_intr.c efx_mac.c
+SRCS+= efx_mcdi.c efx_mon.c efx_nic.c
SRCS+= efx_nvram.c efx_phy.c efx_port.c efx_rx.c efx_sram.c efx_tx.c
-SRCS+= efx_vpd.c efx_wol.c
+SRCS+= efx_vpd.c efx_wol.c efx_filter.c efx_hash.c
SRCS+= efsys.h
-SRCS+= efx.h efx_impl.h efx_mcdi.h efx_regs.h efx_regs_ef10.h
-SRCS+= efx_regs_mcdi.h efx_regs_pci.h efx_types.h
+SRCS+= efx.h efx_check.h efx_impl.h efx_mcdi.h efx_regs.h efx_regs_ef10.h
+SRCS+= efx_regs_mcdi.h efx_regs_pci.h efx_types.h efx_phy_ids.h
+SRCS+= ef10_tlv_layout.h
-SRCS+= siena_mac.c siena_nic.c siena_nvram.c siena_phy.c
+SRCS+= mcdi_mon.c mcdi_mon.h
+
+SRCS+= siena_mac.c siena_mcdi.c siena_nic.c siena_nvram.c siena_phy.c
SRCS+= siena_sram.c siena_vpd.c
SRCS+= siena_flash.h siena_impl.h
-DEBUG_FLAGS= -DDEBUG=1
+SRCS+= hunt_ev.c hunt_intr.c hunt_mac.c hunt_mcdi.c hunt_nic.c
+SRCS+= hunt_nvram.c hunt_rx.c hunt_phy.c hunt_sram.c hunt_tx.c hunt_vpd.c
+SRCS+= hunt_filter.c
+SRCS+= hunt_impl.h
+
+# Extra debug checks
+#CFLAGS += -DDEBUG=1
.include <bsd.kmod.mk>
diff --git a/sys/modules/usb/template/Makefile b/sys/modules/usb/template/Makefile
index fc1cca93d3fa..4164177e8e22 100644
--- a/sys/modules/usb/template/Makefile
+++ b/sys/modules/usb/template/Makefile
@@ -40,6 +40,7 @@ SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h vnode_if.h usbdevs.h \
usb_template_msc.c \
usb_template_mtp.c \
usb_template_phone.c \
- usb_template_serialnet.c
+ usb_template_serialnet.c \
+ usb_template_midi.c
.include <bsd.kmod.mk>
diff --git a/sys/modules/usb/ugold/Makefile b/sys/modules/usb/ugold/Makefile
new file mode 100644
index 000000000000..48af6efa0eb9
--- /dev/null
+++ b/sys/modules/usb/ugold/Makefile
@@ -0,0 +1,13 @@
+#
+# $FreeBSD$
+#
+
+S= ${.CURDIR}/../../..
+
+.PATH: $S/dev/usb/misc
+
+KMOD= ugold
+SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h vnode_if.h \
+ usbdevs.h ugold.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 2fa7e9affb8e..3902227e8c43 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -35,9 +35,10 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
-
#include <sys/socket.h>
+#include <machine/stdarg.h>
+
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
@@ -81,7 +82,7 @@ const int ieee80211_opcap[IEEE80211_OPMODE_MAX] = {
#endif
};
-static const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] =
+const uint8_t ieee80211broadcastaddr[IEEE80211_ADDR_LEN] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static void ieee80211_syncflag_locked(struct ieee80211com *ic, int flag);
@@ -94,6 +95,7 @@ static void ieee80211com_media_status(struct ifnet *, struct ifmediareq *);
static int ieee80211com_media_change(struct ifnet *);
static int media_status(enum ieee80211_opmode,
const struct ieee80211_channel *);
+static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter);
MALLOC_DEFINE(M_80211_VAP, "80211vap", "802.11 vap state");
@@ -223,15 +225,17 @@ ieee80211_chan_init(struct ieee80211com *ic)
}
static void
-null_update_mcast(struct ifnet *ifp)
+null_update_mcast(struct ieee80211com *ic)
{
- if_printf(ifp, "need multicast update callback\n");
+
+ ic_printf(ic, "need multicast update callback\n");
}
static void
-null_update_promisc(struct ifnet *ifp)
+null_update_promisc(struct ieee80211com *ic)
{
- if_printf(ifp, "need promiscuous mode update callback\n");
+
+ ic_printf(ic, "need promiscuous mode update callback\n");
}
static int
@@ -242,15 +246,9 @@ null_transmit(struct ifnet *ifp, struct mbuf *m)
return EACCES; /* XXX EIO/EPERM? */
}
-#if __FreeBSD_version >= 1000031
static int
null_output(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro)
-#else
-static int
-null_output(struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *dst, struct route *ro)
-#endif
{
if_printf(ifp, "discard raw packet\n");
return null_transmit(ifp, m);
@@ -267,7 +265,20 @@ static void
null_update_chw(struct ieee80211com *ic)
{
- if_printf(ic->ic_ifp, "%s: need callback\n", __func__);
+ ic_printf(ic, "%s: need callback\n", __func__);
+}
+
+int
+ic_printf(struct ieee80211com *ic, const char * fmt, ...)
+{
+ va_list ap;
+ int retval;
+
+ retval = printf("%s: ", ic->ic_name);
+ va_start(ap, fmt);
+ retval += vprintf(fmt, ap);
+ va_end(ap);
+ return (retval);
}
/*
@@ -284,15 +295,17 @@ ieee80211_ifattach(struct ieee80211com *ic,
KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));
- IEEE80211_LOCK_INIT(ic, ifp->if_xname);
- IEEE80211_TX_LOCK_INIT(ic, ifp->if_xname);
+ IEEE80211_LOCK_INIT(ic, ic->ic_name);
+ IEEE80211_TX_LOCK_INIT(ic, ic->ic_name);
TAILQ_INIT(&ic->ic_vaps);
/* Create a taskqueue for all state changes */
ic->ic_tq = taskqueue_create("ic_taskq", M_WAITOK | M_ZERO,
taskqueue_thread_enqueue, &ic->ic_tq);
taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
- ifp->if_xname);
+ ic->ic_name);
+ ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
+ ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
/*
* Fill in 802.11 available channel set, mark all
* available channels as active, and pick a default
@@ -391,6 +404,8 @@ ieee80211_ifdetach(struct ieee80211com *ic)
/* XXX VNET needed? */
ifmedia_removeall(&ic->ic_media);
+ counter_u64_free(ic->ic_ierrors);
+ counter_u64_free(ic->ic_oerrors);
taskqueue_free(ic->ic_tq);
IEEE80211_TX_LOCK_DESTROY(ic);
@@ -413,6 +428,31 @@ default_reset(struct ieee80211vap *vap, u_long cmd)
}
/*
+ * Add underlying device errors to vap errors.
+ */
+static uint64_t
+ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt)
+{
+ struct ieee80211vap *vap = ifp->if_softc;
+ struct ieee80211com *ic = vap->iv_ic;
+ uint64_t rv;
+
+ rv = if_get_counter_default(ifp, cnt);
+ switch (cnt) {
+ case IFCOUNTER_OERRORS:
+ rv += counter_u64_fetch(ic->ic_oerrors);
+ break;
+ case IFCOUNTER_IERRORS:
+ rv += counter_u64_fetch(ic->ic_ierrors);
+ break;
+ default:
+ break;
+ }
+
+ return (rv);
+}
+
+/*
* Prepare a vap for use. Drivers use this call to
* setup net80211 state in new vap's prior attaching
* them with ieee80211_vap_attach (below).
@@ -427,7 +467,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
ifp = if_alloc(IFT_ETHER);
if (ifp == NULL) {
- if_printf(ic->ic_ifp, "%s: unable to allocate ifnet\n",
+ ic_printf(ic, "%s: unable to allocate ifnet\n",
__func__);
return ENOMEM;
}
@@ -438,6 +478,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
ifp->if_qflush = ieee80211_vap_qflush;
ifp->if_ioctl = ieee80211_ioctl;
ifp->if_init = ieee80211_init;
+ ifp->if_get_counter = ieee80211_get_counter;
vap->iv_ifp = ifp;
vap->iv_ic = ic;
@@ -551,7 +592,7 @@ ieee80211_vap_attach(struct ieee80211vap *vap,
IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
"%s: %s parent %s flags 0x%x flags_ext 0x%x\n",
__func__, ieee80211_opmode_name[vap->iv_opmode],
- ic->ic_ifp->if_xname, vap->iv_flags, vap->iv_flags_ext);
+ ic->ic_name, vap->iv_flags, vap->iv_flags_ext);
/*
* Do late attach work that cannot happen until after
@@ -607,8 +648,7 @@ ieee80211_vap_detach(struct ieee80211vap *vap)
CURVNET_SET(ifp->if_vnet);
IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s parent %s\n",
- __func__, ieee80211_opmode_name[vap->iv_opmode],
- ic->ic_ifp->if_xname);
+ __func__, ieee80211_opmode_name[vap->iv_opmode], ic->ic_name);
/* NB: bpfdetach is called by ether_ifdetach and claims all taps */
ether_ifdetach(ifp);
@@ -900,7 +940,7 @@ int
ieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c)
{
if (c == NULL) {
- if_printf(ic->ic_ifp, "invalid channel (NULL)\n");
+ ic_printf(ic, "invalid channel (NULL)\n");
return 0; /* XXX */
}
return (c == IEEE80211_CHAN_ANYC ? IEEE80211_CHAN_ANY : c->ic_ieee);
@@ -991,6 +1031,75 @@ ieee80211_find_channel_byieee(struct ieee80211com *ic, int ieee, int flags)
return NULL;
}
+/*
+ * Lookup a channel suitable for the given rx status.
+ *
+ * This is used to find a channel for a frame (eg beacon, probe
+ * response) based purely on the received PHY information.
+ *
+ * For now it tries to do it based on R_FREQ / R_IEEE.
+ * This is enough for 11bg and 11a (and thus 11ng/11na)
+ * but it will not be enough for GSM, PSB channels and the
+ * like. It also doesn't know about legacy-turbog and
+ * legacy-turbo modes, which some offload NICs actually
+ * support in weird ways.
+ *
+ * Takes the ic and rxstatus; returns the channel or NULL
+ * if not found.
+ *
+ * XXX TODO: Add support for that when the need arises.
+ */
+struct ieee80211_channel *
+ieee80211_lookup_channel_rxstatus(struct ieee80211vap *vap,
+ const struct ieee80211_rx_stats *rxs)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+ uint32_t flags;
+ struct ieee80211_channel *c;
+
+ if (rxs == NULL)
+ return (NULL);
+
+ /*
+ * Strictly speaking we only use freq for now,
+ * however later on we may wish to just store
+ * the ieee for verification.
+ */
+ if ((rxs->r_flags & IEEE80211_R_FREQ) == 0)
+ return (NULL);
+ if ((rxs->r_flags & IEEE80211_R_IEEE) == 0)
+ return (NULL);
+
+ /*
+ * If the rx status contains a valid ieee/freq, then
+ * ensure we populate the correct channel information
+ * in rxchan before passing it up to the scan infrastructure.
+ * Offload NICs will pass up beacons from all channels
+ * during background scans.
+ */
+
+ /* Determine a band */
+ /* XXX should be done by the driver? */
+ if (rxs->c_freq < 3000) {
+ flags = IEEE80211_CHAN_G;
+ } else {
+ flags = IEEE80211_CHAN_A;
+ }
+
+ /* Channel lookup */
+ c = ieee80211_find_channel(ic, rxs->c_freq, flags);
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_INPUT,
+ "%s: freq=%d, ieee=%d, flags=0x%08x; c=%p\n",
+ __func__,
+ (int) rxs->c_freq,
+ (int) rxs->c_ieee,
+ flags,
+ c);
+
+ return (c);
+}
+
static void
addmedia(struct ifmedia *media, int caps, int addsta, int mode, int mword)
{
@@ -1169,7 +1278,6 @@ ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *
void
ieee80211_announce(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
int i, rate, mword;
enum ieee80211_phymode mode;
const struct ieee80211_rateset *rs;
@@ -1178,7 +1286,7 @@ ieee80211_announce(struct ieee80211com *ic)
for (mode = IEEE80211_MODE_AUTO+1; mode < IEEE80211_MODE_11NA; mode++) {
if (isclr(ic->ic_modecaps, mode))
continue;
- if_printf(ifp, "%s rates: ", ieee80211_phymode_name[mode]);
+ ic_printf(ic, "%s rates: ", ieee80211_phymode_name[mode]);
rs = &ic->ic_sup_rates[mode];
for (i = 0; i < rs->rs_nrates; i++) {
mword = ieee80211_rate2media(ic, rs->rs_rates[i], mode);
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index 8e586bdd0152..64d0754f358d 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -36,6 +36,10 @@
/* is 802.11 address multicast/broadcast? */
#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01)
+#ifdef _KERNEL
+extern const uint8_t ieee80211broadcastaddr[];
+#endif
+
typedef uint16_t ieee80211_seq;
/* IEEE 802.11 PLCP header */
@@ -812,7 +816,7 @@ struct ieee80211_csa_ie {
#define IEEE80211_RATE_BASIC 0x80
#define IEEE80211_RATE_VAL 0x7f
-/* EPR information element flags */
+/* ERP information element flags */
#define IEEE80211_ERP_NON_ERP_PRESENT 0x01
#define IEEE80211_ERP_USE_PROTECTION 0x02
#define IEEE80211_ERP_LONG_PREAMBLE 0x04
diff --git a/sys/net80211/ieee80211_acl.c b/sys/net80211/ieee80211_acl.c
index ac604fb09206..eeb7f0bc68da 100644
--- a/sys/net80211/ieee80211_acl.c
+++ b/sys/net80211/ieee80211_acl.c
@@ -99,8 +99,8 @@ acl_attach(struct ieee80211vap *vap)
{
struct aclstate *as;
- as = (struct aclstate *) malloc(sizeof(struct aclstate),
- M_80211_ACL, M_NOWAIT | M_ZERO);
+ as = (struct aclstate *) IEEE80211_MALLOC(sizeof(struct aclstate),
+ M_80211_ACL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (as == NULL)
return 0;
ACL_LOCK_INIT(as, "acl");
@@ -123,7 +123,7 @@ acl_detach(struct ieee80211vap *vap)
acl_free_all(vap);
vap->iv_as = NULL;
ACL_LOCK_DESTROY(as);
- free(as, M_80211_ACL);
+ IEEE80211_FREE(as, M_80211_ACL);
}
static __inline struct acl *
@@ -147,7 +147,7 @@ _acl_free(struct aclstate *as, struct acl *acl)
TAILQ_REMOVE(&as->as_list, acl, acl_list);
LIST_REMOVE(acl, acl_hash);
- free(acl, M_80211_ACL);
+ IEEE80211_FREE(acl, M_80211_ACL);
as->as_nacls--;
}
@@ -175,7 +175,8 @@ acl_add(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
struct acl *acl, *new;
int hash;
- new = (struct acl *) malloc(sizeof(struct acl), M_80211_ACL, M_NOWAIT | M_ZERO);
+ new = (struct acl *) IEEE80211_MALLOC(sizeof(struct acl),
+ M_80211_ACL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (new == NULL) {
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
"ACL: add %s failed, no memory\n", ether_sprintf(mac));
@@ -188,7 +189,7 @@ acl_add(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) {
if (IEEE80211_ADDR_EQ(acl->acl_macaddr, mac)) {
ACL_UNLOCK(as);
- free(new, M_80211_ACL);
+ IEEE80211_FREE(new, M_80211_ACL);
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
"ACL: add %s failed, already present\n",
ether_sprintf(mac));
@@ -302,8 +303,8 @@ acl_getioctl(struct ieee80211vap *vap, struct ieee80211req *ireq)
ireq->i_len = space; /* return required space */
return 0; /* NB: must not error */
}
- ap = (struct ieee80211req_maclist *) malloc(space,
- M_TEMP, M_NOWAIT);
+ ap = (struct ieee80211req_maclist *) IEEE80211_MALLOC(space,
+ M_TEMP, IEEE80211_M_NOWAIT);
if (ap == NULL)
return ENOMEM;
i = 0;
@@ -318,7 +319,7 @@ acl_getioctl(struct ieee80211vap *vap, struct ieee80211req *ireq)
ireq->i_len = space;
} else
error = copyout(ap, ireq->i_data, ireq->i_len);
- free(ap, M_TEMP);
+ IEEE80211_FREE(ap, M_TEMP);
return error;
}
return EINVAL;
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index 0d761c4af985..d31ad9be0de6 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -70,11 +70,12 @@ __FBSDID("$FreeBSD$");
static void adhoc_vattach(struct ieee80211vap *);
static int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static int adhoc_input(struct ieee80211_node *, struct mbuf *, int, int);
+static int adhoc_input(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_rx_stats *, int, int);
static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int, int);
+ int subtype, const struct ieee80211_rx_stats *, int, int);
static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int, int);
+ int subtype, const struct ieee80211_rx_stats *rxs, int, int);
static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
void
@@ -289,7 +290,8 @@ doprint(struct ieee80211vap *vap, int subtype)
* by the 802.11 layer.
*/
static int
-adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -642,7 +644,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
goto out;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
@@ -687,10 +689,11 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates)
static void
adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_channel *rxchan = ic->ic_curchan;
struct ieee80211_frame *wh;
uint8_t *frm, *efrm, *sfrm;
uint8_t *ssid, *rates, *xrates;
@@ -705,11 +708,17 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
case IEEE80211_FC0_SUBTYPE_BEACON: {
struct ieee80211_scanparams scan;
+ struct ieee80211_channel *c;
/*
* We process beacon/probe response
* frames to discover neighbors.
*/
- if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
+ if (rxs != NULL) {
+ c = ieee80211_lookup_channel_rxstatus(vap, rxs);
+ if (c != NULL)
+ rxchan = c;
+ }
+ if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0)
return;
/*
* Count frame now that we know it's to be processed.
@@ -735,7 +744,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
ieee80211_probe_curchan(vap, 1);
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
}
- ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh,
+ ieee80211_add_scan(vap, rxchan, &scan, wh,
subtype, rssi, nf);
return;
}
@@ -911,7 +920,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
static void
ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -922,7 +931,7 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
* a site-survey.
*/
if (ic->ic_flags & IEEE80211_F_SCAN)
- adhoc_recv_mgmt(ni, m0, subtype, rssi, nf);
+ adhoc_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
else {
wh = mtod(m0, struct ieee80211_frame *);
switch (subtype) {
diff --git a/sys/net80211/ieee80211_amrr.c b/sys/net80211/ieee80211_amrr.c
index b1d92c880fc0..b7c11fd2417b 100644
--- a/sys/net80211/ieee80211_amrr.c
+++ b/sys/net80211/ieee80211_amrr.c
@@ -113,8 +113,8 @@ amrr_init(struct ieee80211vap *vap)
KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__));
- amrr = vap->iv_rs = malloc(sizeof(struct ieee80211_amrr),
- M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ amrr = vap->iv_rs = IEEE80211_MALLOC(sizeof(struct ieee80211_amrr),
+ M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (amrr == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n");
return;
@@ -128,7 +128,7 @@ amrr_init(struct ieee80211vap *vap)
static void
amrr_deinit(struct ieee80211vap *vap)
{
- free(vap->iv_rs, M_80211_RATECTL);
+ IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL);
}
/*
@@ -160,8 +160,8 @@ amrr_node_init(struct ieee80211_node *ni)
uint8_t rate;
if (ni->ni_rctls == NULL) {
- ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node),
- M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ ni->ni_rctls = amn = IEEE80211_MALLOC(sizeof(struct ieee80211_amrr_node),
+ M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (amn == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
"structure\n");
@@ -225,7 +225,7 @@ amrr_node_init(struct ieee80211_node *ni)
static void
amrr_node_deinit(struct ieee80211_node *ni)
{
- free(ni->ni_rctls, M_80211_RATECTL);
+ IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL);
}
static int
diff --git a/sys/net80211/ieee80211_crypto_ccmp.c b/sys/net80211/ieee80211_crypto_ccmp.c
index cb9ed0af0149..89ca6d07e8e7 100644
--- a/sys/net80211/ieee80211_crypto_ccmp.c
+++ b/sys/net80211/ieee80211_crypto_ccmp.c
@@ -96,8 +96,8 @@ ccmp_attach(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct ccmp_ctx *ctx;
- ctx = (struct ccmp_ctx *) malloc(sizeof(struct ccmp_ctx),
- M_80211_CRYPTO, M_NOWAIT | M_ZERO);
+ ctx = (struct ccmp_ctx *) IEEE80211_MALLOC(sizeof(struct ccmp_ctx),
+ M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ctx == NULL) {
vap->iv_stats.is_crypto_nomem++;
return NULL;
@@ -113,7 +113,7 @@ ccmp_detach(struct ieee80211_key *k)
{
struct ccmp_ctx *ctx = k->wk_private;
- free(ctx, M_80211_CRYPTO);
+ IEEE80211_FREE(ctx, M_80211_CRYPTO);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
nrefs--; /* NB: we assume caller locking */
}
diff --git a/sys/net80211/ieee80211_crypto_tkip.c b/sys/net80211/ieee80211_crypto_tkip.c
index 05d9c74bdf28..c6d2f541c87a 100644
--- a/sys/net80211/ieee80211_crypto_tkip.c
+++ b/sys/net80211/ieee80211_crypto_tkip.c
@@ -109,8 +109,8 @@ tkip_attach(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct tkip_ctx *ctx;
- ctx = (struct tkip_ctx *) malloc(sizeof(struct tkip_ctx),
- M_80211_CRYPTO, M_NOWAIT | M_ZERO);
+ ctx = (struct tkip_ctx *) IEEE80211_MALLOC(sizeof(struct tkip_ctx),
+ M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ctx == NULL) {
vap->iv_stats.is_crypto_nomem++;
return NULL;
@@ -126,7 +126,7 @@ tkip_detach(struct ieee80211_key *k)
{
struct tkip_ctx *ctx = k->wk_private;
- free(ctx, M_80211_CRYPTO);
+ IEEE80211_FREE(ctx, M_80211_CRYPTO);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
nrefs--; /* NB: we assume caller locking */
}
diff --git a/sys/net80211/ieee80211_crypto_wep.c b/sys/net80211/ieee80211_crypto_wep.c
index 07c1797571a2..587cf39ce35d 100644
--- a/sys/net80211/ieee80211_crypto_wep.c
+++ b/sys/net80211/ieee80211_crypto_wep.c
@@ -87,8 +87,8 @@ wep_attach(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct wep_ctx *ctx;
- ctx = (struct wep_ctx *) malloc(sizeof(struct wep_ctx),
- M_80211_CRYPTO, M_NOWAIT | M_ZERO);
+ ctx = (struct wep_ctx *) IEEE80211_MALLOC(sizeof(struct wep_ctx),
+ M_80211_CRYPTO, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ctx == NULL) {
vap->iv_stats.is_crypto_nomem++;
return NULL;
@@ -106,7 +106,7 @@ wep_detach(struct ieee80211_key *k)
{
struct wep_ctx *ctx = k->wk_private;
- free(ctx, M_80211_CRYPTO);
+ IEEE80211_FREE(ctx, M_80211_CRYPTO);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
nrefs--; /* NB: we assume caller locking */
}
diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c
index 74e82e545135..e646cf2b7417 100644
--- a/sys/net80211/ieee80211_ddb.c
+++ b/sys/net80211/ieee80211_ddb.c
@@ -521,6 +521,7 @@ _db_show_com(const struct ieee80211com *ic, int showvaps, int showsta,
db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap);
db_printf("\n");
db_printf("\tifp %p(%s)", ic->ic_ifp, ic->ic_ifp->if_xname);
+ db_printf("\tname %s", ic->ic_name);
db_printf(" comlock %p", &ic->ic_comlock);
db_printf("\n");
db_printf("\theadroom %d", ic->ic_headroom);
diff --git a/sys/net80211/ieee80211_dfs.c b/sys/net80211/ieee80211_dfs.c
index 5fa9ba4b5c3a..232ceb7c6c0e 100644
--- a/sys/net80211/ieee80211_dfs.c
+++ b/sys/net80211/ieee80211_dfs.c
@@ -253,8 +253,8 @@ dfs_timeout(void *arg)
* msg instead of one for every channel
* table entry.
*/
- if_printf(ic->ic_ifp, "radar on channel"
- " %u (%u MHz) cleared after timeout\n",
+ ic_printf(ic, "radar on channel %u "
+ "(%u MHz) cleared after timeout\n",
c->ic_ieee, c->ic_freq);
/* notify user space */
c->ic_state &=
@@ -272,14 +272,14 @@ dfs_timeout(void *arg)
}
static void
-announce_radar(struct ifnet *ifp, const struct ieee80211_channel *curchan,
+announce_radar(struct ieee80211com *ic, const struct ieee80211_channel *curchan,
const struct ieee80211_channel *newchan)
{
if (newchan == NULL)
- if_printf(ifp, "radar detected on channel %u (%u MHz)\n",
+ ic_printf(ic, "radar detected on channel %u (%u MHz)\n",
curchan->ic_ieee, curchan->ic_freq);
else
- if_printf(ifp, "radar detected on channel %u (%u MHz), "
+ ic_printf(ic, "radar detected on channel %u (%u MHz), "
"moving to channel %u (%u MHz)\n",
curchan->ic_ieee, curchan->ic_freq,
newchan->ic_ieee, newchan->ic_freq);
@@ -309,7 +309,7 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
* along merrily.
*/
if (ieee80211_dfs_debug == DFS_DBG_NOCSANOL) {
- announce_radar(ic->ic_ifp, chan, chan);
+ announce_radar(ic, chan, chan);
ieee80211_notify_radar(ic, chan);
return;
}
@@ -364,7 +364,7 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
else
dfs->newchan = chan;
- announce_radar(ic->ic_ifp, chan, dfs->newchan);
+ announce_radar(ic, chan, dfs->newchan);
if (callout_pending(&dfs->cac_timer))
callout_schedule(&dfs->cac_timer, 0);
@@ -380,7 +380,7 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
* on the NOL to expire.
*/
/*XXX*/
- if_printf(ic->ic_ifp, "%s: No free channels; waiting for entry "
+ ic_printf(ic, "%s: No free channels; waiting for entry "
"on NOL to expire\n", __func__);
}
} else {
@@ -390,9 +390,9 @@ ieee80211_dfs_notify_radar(struct ieee80211com *ic, struct ieee80211_channel *ch
if (dfs->lastchan != chan) {
dfs->lastchan = chan;
dfs->cureps = 0;
- announce_radar(ic->ic_ifp, chan, NULL);
+ announce_radar(ic, chan, NULL);
} else if (ppsratecheck(&dfs->lastevent, &dfs->cureps, 1)) {
- announce_radar(ic->ic_ifp, chan, NULL);
+ announce_radar(ic, chan, NULL);
}
}
}
@@ -434,6 +434,6 @@ ieee80211_dfs_pickchannel(struct ieee80211com *ic)
(c->ic_flags & flags) == flags)
return c;
}
- if_printf(ic->ic_ifp, "HELP, no channel located to switch to!\n");
+ ic_printf(ic, "HELP, no channel located to switch to!\n");
return NULL;
}
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 7a2abf85a23f..3af75dfc78c0 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -66,10 +66,8 @@ SYSCTL_INT(_net_wlan, OID_AUTO, debug, CTLFLAG_RW, &ieee80211_debug,
static MALLOC_DEFINE(M_80211_COM, "80211com", "802.11 com state");
-#if __FreeBSD_version >= 1000020
static const char wlanname[] = "wlan";
static struct if_clone *wlan_cloner;
-#endif
/*
* Allocate/free com structure in conjunction with ifnet;
@@ -82,7 +80,8 @@ wlan_alloc(u_char type, struct ifnet *ifp)
{
struct ieee80211com *ic;
- ic = malloc(sizeof(struct ieee80211com), M_80211_COM, M_WAITOK|M_ZERO);
+ ic = IEEE80211_MALLOC(sizeof(struct ieee80211com), M_80211_COM,
+ IEEE80211_M_WAITOK | IEEE80211_M_ZERO);
ic->ic_ifp = ifp;
return (ic);
@@ -91,7 +90,7 @@ wlan_alloc(u_char type, struct ifnet *ifp)
static void
wlan_free(void *ic, u_char type)
{
- free(ic, M_80211_COM);
+ IEEE80211_FREE(ic, M_80211_COM);
}
static int
@@ -135,18 +134,10 @@ wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
if_printf(ifp, "TDMA not supported\n");
return EOPNOTSUPP;
}
-#if __FreeBSD_version >= 1000020
vap = ic->ic_vap_create(ic, wlanname, unit,
cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
cp.icp_flags & IEEE80211_CLONE_MACADDR ?
cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
-#else
- vap = ic->ic_vap_create(ic, ifc->ifc_name, unit,
- cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
- cp.icp_flags & IEEE80211_CLONE_MACADDR ?
- cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
-
-#endif
return (vap == NULL ? EIO : 0);
}
@@ -160,19 +151,11 @@ wlan_clone_destroy(struct ifnet *ifp)
ic->ic_vap_delete(vap);
}
-#if __FreeBSD_version < 1000020
-IFC_SIMPLE_DECLARE(wlan, 0);
-#endif
-
void
ieee80211_vap_destroy(struct ieee80211vap *vap)
{
CURVNET_SET(vap->iv_ifp->if_vnet);
-#if __FreeBSD_version >= 1000020
if_clone_destroyif(wlan_cloner, vap->iv_ifp);
-#else
- if_clone_destroyif(&wlan_cloner, vap->iv_ifp);
-#endif
CURVNET_RESTORE();
}
@@ -207,9 +190,8 @@ static int
ieee80211_sysctl_parent(SYSCTL_HANDLER_ARGS)
{
struct ieee80211com *ic = arg1;
- const char *name = ic->ic_ifp->if_xname;
- return SYSCTL_OUT_STR(req, name);
+ return SYSCTL_OUT_STR(req, ic->ic_name);
}
static int
@@ -245,8 +227,8 @@ ieee80211_sysctl_vattach(struct ieee80211vap *vap)
struct sysctl_oid *oid;
char num[14]; /* sufficient for 32 bits */
- ctx = (struct sysctl_ctx_list *) malloc(sizeof(struct sysctl_ctx_list),
- M_DEVBUF, M_NOWAIT | M_ZERO);
+ ctx = (struct sysctl_ctx_list *) IEEE80211_MALLOC(sizeof(struct sysctl_ctx_list),
+ M_DEVBUF, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ctx == NULL) {
if_printf(ifp, "%s: cannot allocate sysctl context!\n",
__func__);
@@ -321,7 +303,7 @@ ieee80211_sysctl_vdetach(struct ieee80211vap *vap)
if (vap->iv_sysctl != NULL) {
sysctl_ctx_free(vap->iv_sysctl);
- free(vap->iv_sysctl, M_DEVBUF);
+ IEEE80211_FREE(vap->iv_sysctl, M_DEVBUF);
vap->iv_sysctl = NULL;
}
}
@@ -492,6 +474,40 @@ ieee80211_add_callback(struct mbuf *m,
return 1;
}
+int
+ieee80211_add_xmit_params(struct mbuf *m,
+ const struct ieee80211_bpf_params *params)
+{
+ struct m_tag *mtag;
+ struct ieee80211_tx_params *tx;
+
+ mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
+ sizeof(struct ieee80211_tx_params), M_NOWAIT);
+ if (mtag == NULL)
+ return (0);
+
+ tx = (struct ieee80211_tx_params *)(mtag+1);
+ memcpy(&tx->params, params, sizeof(struct ieee80211_bpf_params));
+ m_tag_prepend(m, mtag);
+ return (1);
+}
+
+int
+ieee80211_get_xmit_params(struct mbuf *m,
+ struct ieee80211_bpf_params *params)
+{
+ struct m_tag *mtag;
+ struct ieee80211_tx_params *tx;
+
+ mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
+ NULL);
+ if (mtag == NULL)
+ return (-1);
+ tx = (struct ieee80211_tx_params *)(mtag + 1);
+ memcpy(params, &tx->params, sizeof(struct ieee80211_bpf_params));
+ return (0);
+}
+
void
ieee80211_process_callback(struct ieee80211_node *ni,
struct mbuf *m, int status)
@@ -694,8 +710,9 @@ void
ieee80211_notify_csa(struct ieee80211com *ic,
const struct ieee80211_channel *c, int mode, int count)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_csa_event iev;
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
memset(&iev, 0, sizeof(iev));
iev.iev_flags = c->ic_flags;
@@ -703,42 +720,53 @@ ieee80211_notify_csa(struct ieee80211com *ic,
iev.iev_ieee = c->ic_ieee;
iev.iev_mode = mode;
iev.iev_count = count;
- CURVNET_SET(ifp->if_vnet);
- rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
- CURVNET_RESTORE();
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ CURVNET_SET(ifp->if_vnet);
+ rt_ieee80211msg(ifp, RTM_IEEE80211_CSA, &iev, sizeof(iev));
+ CURVNET_RESTORE();
+ }
}
void
ieee80211_notify_radar(struct ieee80211com *ic,
const struct ieee80211_channel *c)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_radar_event iev;
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
memset(&iev, 0, sizeof(iev));
iev.iev_flags = c->ic_flags;
iev.iev_freq = c->ic_freq;
iev.iev_ieee = c->ic_ieee;
- CURVNET_SET(ifp->if_vnet);
- rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
- CURVNET_RESTORE();
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ CURVNET_SET(ifp->if_vnet);
+ rt_ieee80211msg(ifp, RTM_IEEE80211_RADAR, &iev, sizeof(iev));
+ CURVNET_RESTORE();
+ }
}
void
ieee80211_notify_cac(struct ieee80211com *ic,
const struct ieee80211_channel *c, enum ieee80211_notify_cac_event type)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_cac_event iev;
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
memset(&iev, 0, sizeof(iev));
iev.iev_flags = c->ic_flags;
iev.iev_freq = c->ic_freq;
iev.iev_ieee = c->ic_ieee;
iev.iev_type = type;
- CURVNET_SET(ifp->if_vnet);
- rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
- CURVNET_RESTORE();
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ CURVNET_SET(ifp->if_vnet);
+ rt_ieee80211msg(ifp, RTM_IEEE80211_CAC, &iev, sizeof(iev));
+ CURVNET_RESTORE();
+ }
}
void
@@ -782,14 +810,18 @@ ieee80211_notify_country(struct ieee80211vap *vap,
void
ieee80211_notify_radio(struct ieee80211com *ic, int state)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211_radio_event iev;
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
memset(&iev, 0, sizeof(iev));
iev.iev_state = state;
- CURVNET_SET(ifp->if_vnet);
- rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
- CURVNET_RESTORE();
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ ifp = vap->iv_ifp;
+ CURVNET_SET(ifp->if_vnet);
+ rt_ieee80211msg(ifp, RTM_IEEE80211_RADIO, &iev, sizeof(iev));
+ CURVNET_RESTORE();
+ }
}
void
@@ -875,21 +907,13 @@ wlan_modevent(module_t mod, int type, void *unused)
bpf_track, 0, EVENTHANDLER_PRI_ANY);
wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
-#if __FreeBSD_version >= 1000020
wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
wlan_clone_destroy, 0);
-#else
- if_clone_attach(&wlan_cloner);
-#endif
if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
return 0;
case MOD_UNLOAD:
if_deregister_com_alloc(IFT_IEEE80211);
-#if __FreeBSD_version >= 1000020
if_clone_detach(wlan_cloner);
-#else
- if_clone_detach(&wlan_cloner);
-#endif
EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
return 0;
@@ -898,11 +922,7 @@ wlan_modevent(module_t mod, int type, void *unused)
}
static moduledata_t wlan_mod = {
-#if __FreeBSD_version >= 1000020
wlanname,
-#else
- "wlan",
-#endif
wlan_modevent,
0
};
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index aa21f3b9e218..162cf4309d49 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -28,7 +28,9 @@
#define _NET80211_IEEE80211_FREEBSD_H_
#ifdef _KERNEL
-#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/counter.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
@@ -183,6 +185,34 @@ typedef struct mtx ieee80211_scan_table_lock_t;
#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock)
#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock)
+typedef struct mtx ieee80211_scan_iter_lock_t;
+#define IEEE80211_SCAN_ITER_LOCK_INIT(_st, _name) \
+ mtx_init(&(_st)->st_scanlock, _name, "802.11 scangen", MTX_DEF)
+#define IEEE80211_SCAN_ITER_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_scanlock)
+#define IEEE80211_SCAN_ITER_LOCK(_st) mtx_lock(&(_st)->st_scanlock)
+#define IEEE80211_SCAN_ITER_UNLOCK(_st) mtx_unlock(&(_st)->st_scanlock)
+
+/*
+ * Mesh node/routing definitions.
+ */
+typedef struct mtx ieee80211_rte_lock_t;
+#define MESH_RT_ENTRY_LOCK_INIT(_rt, _name) \
+ mtx_init(&(rt)->rt_lock, _name, "802.11s route entry", MTX_DEF)
+#define MESH_RT_ENTRY_LOCK_DESTROY(_rt) \
+ mtx_destroy(&(_rt)->rt_lock)
+#define MESH_RT_ENTRY_LOCK(rt) mtx_lock(&(rt)->rt_lock)
+#define MESH_RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED)
+#define MESH_RT_ENTRY_UNLOCK(rt) mtx_unlock(&(rt)->rt_lock)
+
+typedef struct mtx ieee80211_rt_lock_t;
+#define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock)
+#define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
+#define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock)
+#define MESH_RT_LOCK_INIT(ms, name) \
+ mtx_init(&(ms)->ms_rt_lock, name, "802.11s routing table", MTX_DEF)
+#define MESH_RT_LOCK_DESTROY(ms) \
+ mtx_destroy(&(ms)->ms_rt_lock)
+
/*
* Node reference counting definitions.
*
@@ -234,21 +264,9 @@ struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
#define M_FF M_PROTO6 /* fast frame */
#define M_TXCB M_PROTO7 /* do tx complete callback */
#define M_AMPDU_MPDU M_PROTO8 /* ok for A-MPDU aggregation */
-
-/*
- * FreeBSD-HEAD from 1000046 retired M_*FRAG* flags and turned them
- * into header flags instead. So, we use the new protocol-specific
- * flags.
- *
- * Earlier FreeBSD versions overload M_FRAG, M_FIRSTFRAG and M_LASTFRAG.
- *
- * XXX TODO: rename these fields so there are no namespace clashes!
- */
-#if __FreeBSD_version >= 1000046
#define M_FRAG M_PROTO9 /* frame fragmentation */
#define M_FIRSTFRAG M_PROTO10 /* first frame fragment */
#define M_LASTFRAG M_PROTO11 /* last frame fragment */
-#endif
#define M_80211_TX \
(M_ENCAP|M_EAPOL|M_PWR_SAV|M_MORE_DATA|M_FF|M_TXCB| \
@@ -262,18 +280,10 @@ struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
#endif
#define M_80211_RX (M_AMPDU|M_WEP|M_AMPDU_MPDU)
-#if __FreeBSD_version >= 1000046
#define IEEE80211_MBUF_TX_FLAG_BITS \
M_FLAG_BITS \
"\15M_ENCAP\17M_EAPOL\20M_PWR_SAV\21M_MORE_DATA\22M_FF\23M_TXCB" \
"\24M_AMPDU_MPDU\25M_FRAG\26M_FIRSTFRAG\27M_LASTFRAG"
-#else
-/* There aren't any flag bits available for versions before this */
-/* XXX TODO: implement M_FLAG_BITS for this! */
-#define IEEE80211_MBUF_TX_FLAG_BITS \
- "\15M_ENCAP\17M_EAPOL\20M_PWR_SAV\21M_MORE_DATA\22M_FF\23M_TXCB" \
- "\24M_AMPDU_MPDU"
-#endif
#define IEEE80211_MBUF_RX_FLAG_BITS \
M_FLAG_BITS \
@@ -317,6 +327,9 @@ int ieee80211_add_callback(struct mbuf *m,
void (*func)(struct ieee80211_node *, void *, int), void *arg);
void ieee80211_process_callback(struct ieee80211_node *, struct mbuf *, int);
+#define NET80211_TAG_XMIT_PARAMS 1
+/* See below; this is after the bpf_params definition */
+
struct ieee80211com;
int ieee80211_parent_xmitpkt(struct ieee80211com *, struct mbuf *);
int ieee80211_vap_xmitpkt(struct ieee80211vap *, struct mbuf *);
@@ -596,4 +609,29 @@ struct ieee80211_bpf_params {
uint8_t ibp_try3; /* series 4 try count */
uint8_t ibp_rate3; /* series 4 IEEE tx rate */
};
+
+#ifdef _KERNEL
+struct ieee80211_tx_params {
+ struct ieee80211_bpf_params params;
+};
+int ieee80211_add_xmit_params(struct mbuf *m,
+ const struct ieee80211_bpf_params *);
+int ieee80211_get_xmit_params(struct mbuf *m,
+ struct ieee80211_bpf_params *);
+#endif /* _KERNEL */
+
+/*
+ * Malloc API. Other BSD operating systems have slightly
+ * different malloc/free namings (eg DragonflyBSD.)
+ */
+#define IEEE80211_MALLOC malloc
+#define IEEE80211_FREE free
+
+/* XXX TODO: get rid of WAITOK, fix all the users of it? */
+#define IEEE80211_M_NOWAIT M_NOWAIT
+#define IEEE80211_M_WAITOK M_WAITOK
+#define IEEE80211_M_ZERO M_ZERO
+
+/* XXX TODO: the type fields */
+
#endif /* _NET80211_IEEE80211_FREEBSD_H_ */
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index a625b4e95a22..ccb31abc6666 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -68,11 +68,12 @@ __FBSDID("$FreeBSD$");
static void hostap_vattach(struct ieee80211vap *);
static int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int hostap_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *,
int rssi, int nf);
static void hostap_deliver_data(struct ieee80211vap *,
struct ieee80211_node *, struct mbuf *);
static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int rssi, int nf);
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf);
static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
void
@@ -356,12 +357,8 @@ hostap_deliver_data(struct ieee80211vap *vap,
struct ifnet *ifp = vap->iv_ifp;
/* clear driver/net80211 flags before passing up */
-#if __FreeBSD_version >= 1000046
m->m_flags &= ~(M_MCAST | M_BCAST);
m_clrprotoflags(m);
-#else
- m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST);
-#endif
KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP,
("gack, opmode %d", vap->iv_opmode));
@@ -476,7 +473,8 @@ doprint(struct ieee80211vap *vap, int subtype)
* by the 802.11 layer.
*/
static int
-hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+hostap_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -893,7 +891,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
if (ieee80211_radiotap_active_vap(vap))
ieee80211_radiotap_rx(vap, m);
need_tap = 0;
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
@@ -937,7 +935,7 @@ hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh,
* open auth is attempted.
*/
if (ni->ni_challenge != NULL) {
- free(ni->ni_challenge, M_80211_NODE);
+ IEEE80211_FREE(ni->ni_challenge, M_80211_NODE);
ni->ni_challenge = NULL;
}
/* XXX hack to workaround calling convention */
@@ -1681,7 +1679,7 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates)
static void
hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -1709,7 +1707,8 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
return;
}
/* NB: accept off-channel frames */
- if (ieee80211_parse_beacon(ni, m0, &scan) &~ IEEE80211_BPARSE_OFFCHAN)
+ /* XXX TODO: use rxstatus to determine off-channel details */
+ if (ieee80211_parse_beacon(ni, m0, ic->ic_curchan, &scan) &~ IEEE80211_BPARSE_OFFCHAN)
return;
/*
* Count frame now that we know it's to be processed.
@@ -2039,7 +2038,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
return;
/* discard challenge after association */
if (ni->ni_challenge != NULL) {
- free(ni->ni_challenge, M_80211_NODE);
+ IEEE80211_FREE(ni->ni_challenge, M_80211_NODE);
ni->ni_challenge = NULL;
}
/* NB: 802.11 spec says to ignore station's privacy bit */
diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c
index 0700de8cc7bb..d83cf6511f2f 100644
--- a/sys/net80211/ieee80211_ht.c
+++ b/sys/net80211/ieee80211_ht.c
@@ -354,7 +354,6 @@ static struct printranges {
static void
ht_rateprint(struct ieee80211com *ic, enum ieee80211_phymode mode, int ratetype)
{
- struct ifnet *ifp = ic->ic_ifp;
int minrate, maxrate;
struct printranges *range;
@@ -369,12 +368,12 @@ ht_rateprint(struct ieee80211com *ic, enum ieee80211_phymode mode, int ratetype)
minrate = ht_getrate(ic, range->minmcs, mode, ratetype);
maxrate = ht_getrate(ic, range->maxmcs, mode, ratetype);
if (range->maxmcs) {
- if_printf(ifp, "MCS %d-%d: %d%sMbps - %d%sMbps\n",
+ ic_printf(ic, "MCS %d-%d: %d%sMbps - %d%sMbps\n",
range->minmcs, range->maxmcs,
minrate/2, ((minrate & 0x1) != 0 ? ".5" : ""),
maxrate/2, ((maxrate & 0x1) != 0 ? ".5" : ""));
} else {
- if_printf(ifp, "MCS %d: %d%sMbps\n", range->minmcs,
+ ic_printf(ic, "MCS %d: %d%sMbps\n", range->minmcs,
minrate/2, ((minrate & 0x1) != 0 ? ".5" : ""));
}
}
@@ -383,22 +382,21 @@ ht_rateprint(struct ieee80211com *ic, enum ieee80211_phymode mode, int ratetype)
static void
ht_announce(struct ieee80211com *ic, enum ieee80211_phymode mode)
{
- struct ifnet *ifp = ic->ic_ifp;
const char *modestr = ieee80211_phymode_name[mode];
- if_printf(ifp, "%s MCS 20MHz\n", modestr);
+ ic_printf(ic, "%s MCS 20MHz\n", modestr);
ht_rateprint(ic, mode, 0);
if (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) {
- if_printf(ifp, "%s MCS 20MHz SGI\n", modestr);
+ ic_printf(ic, "%s MCS 20MHz SGI\n", modestr);
ht_rateprint(ic, mode, 1);
}
if (ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) {
- if_printf(ifp, "%s MCS 40MHz:\n", modestr);
+ ic_printf(ic, "%s MCS 40MHz:\n", modestr);
ht_rateprint(ic, mode, 2);
}
if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) &&
(ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40)) {
- if_printf(ifp, "%s MCS 40MHz SGI:\n", modestr);
+ ic_printf(ic, "%s MCS 40MHz SGI:\n", modestr);
ht_rateprint(ic, mode, 3);
}
}
@@ -406,11 +404,10 @@ ht_announce(struct ieee80211com *ic, enum ieee80211_phymode mode)
void
ieee80211_ht_announce(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA) ||
isset(ic->ic_modecaps, IEEE80211_MODE_11NG))
- if_printf(ifp, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream);
+ ic_printf(ic, "%dT%dR\n", ic->ic_txstream, ic->ic_rxstream);
if (isset(ic->ic_modecaps, IEEE80211_MODE_11NA))
ht_announce(ic, IEEE80211_MODE_11NA);
if (isset(ic->ic_modecaps, IEEE80211_MODE_11NG))
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 601b848310d6..6bbc32c634dc 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -268,8 +268,8 @@ hwmp_vattach(struct ieee80211vap *vap)
KASSERT(vap->iv_opmode == IEEE80211_M_MBSS,
("not a mesh vap, opmode %d", vap->iv_opmode));
- hs = malloc(sizeof(struct ieee80211_hwmp_state), M_80211_VAP,
- M_NOWAIT | M_ZERO);
+ hs = IEEE80211_MALLOC(sizeof(struct ieee80211_hwmp_state), M_80211_VAP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (hs == NULL) {
printf("%s: couldn't alloc HWMP state\n", __func__);
return;
@@ -285,7 +285,7 @@ hwmp_vdetach(struct ieee80211vap *vap)
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
callout_drain(&hs->hs_roottimer);
- free(vap->iv_hwmp, M_80211_VAP);
+ IEEE80211_FREE(vap->iv_hwmp, M_80211_VAP);
vap->iv_hwmp = NULL;
}
@@ -429,9 +429,10 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
vap->iv_stats.is_rx_mgtdiscard++;
break;
}
- preq = malloc(sizeof(*preq) +
+ preq = IEEE80211_MALLOC(sizeof(*preq) +
(ndest - 1) * sizeof(*preq->preq_targets),
- M_80211_MESH_PREQ, M_NOWAIT | M_ZERO);
+ M_80211_MESH_PREQ,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
KASSERT(preq != NULL, ("preq == NULL"));
preq->preq_ie = *iefrm_t++;
@@ -464,7 +465,7 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
}
hwmp_recv_preq(vap, ni, wh, preq);
- free(preq, M_80211_MESH_PREQ);
+ IEEE80211_FREE(preq, M_80211_MESH_PREQ);
found++;
break;
}
@@ -476,8 +477,9 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
vap->iv_stats.is_rx_mgtdiscard++;
break;
}
- prep = malloc(sizeof(*prep),
- M_80211_MESH_PREP, M_NOWAIT | M_ZERO);
+ prep = IEEE80211_MALLOC(sizeof(*prep),
+ M_80211_MESH_PREP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
KASSERT(prep != NULL, ("prep == NULL"));
prep->prep_ie = *iefrm_t++;
@@ -501,7 +503,7 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
prep->prep_origseq = LE_READ_4(iefrm_t); iefrm_t += 4;
hwmp_recv_prep(vap, ni, wh, prep);
- free(prep, M_80211_MESH_PREP);
+ IEEE80211_FREE(prep, M_80211_MESH_PREP);
found++;
break;
}
@@ -515,9 +517,10 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
vap->iv_stats.is_rx_mgtdiscard++;
break;
}
- perr = malloc(sizeof(*perr) +
+ perr = IEEE80211_MALLOC(sizeof(*perr) +
(ndest - 1) * sizeof(*perr->perr_dests),
- M_80211_MESH_PERR, M_NOWAIT | M_ZERO);
+ M_80211_MESH_PERR,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
KASSERT(perr != NULL, ("perr == NULL"));
perr->perr_ie = *iefrm_t++;
@@ -546,7 +549,7 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni,
}
hwmp_recv_perr(vap, ni, wh, perr);
- free(perr, M_80211_MESH_PERR);
+ IEEE80211_FREE(perr, M_80211_MESH_PERR);
found++;
break;
}
@@ -1556,8 +1559,8 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
*/
if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) {
forward = 1;
- pperr = malloc(sizeof(*perr) + 31*sizeof(*perr->perr_dests),
- M_80211_MESH_PERR, M_NOWAIT); /* XXX: magic number, 32 err dests */
+ pperr = IEEE80211_MALLOC(sizeof(*perr) + 31*sizeof(*perr->perr_dests),
+ M_80211_MESH_PERR, IEEE80211_M_NOWAIT); /* XXX: magic number, 32 err dests */
}
/*
@@ -1632,7 +1635,7 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
}
done:
if (pperr != NULL)
- free(pperr, M_80211_MESH_PERR);
+ IEEE80211_FREE(pperr, M_80211_MESH_PERR);
}
#undef PERR_DFLAGS
#undef PERR_DADDR
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index a0f737dc2036..b757ae635f9f 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -88,7 +88,8 @@ ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m,
{
/* XXX should assert IEEE80211_R_NF and IEEE80211_R_RSSI are set */
ieee80211_process_mimo(ni, rx);
- return ieee80211_input(ni, m, rx->rssi, rx->nf);
+ //return ieee80211_input(ni, m, rx->rssi, rx->nf);
+ return ni->ni_vap->iv_input(ni, m, rx, rx->rssi, rx->nf);
}
int
@@ -252,9 +253,7 @@ ieee80211_deliver_data(struct ieee80211vap *vap,
/* clear driver/net80211 flags before passing up */
m->m_flags &= ~(M_MCAST | M_BCAST);
-#if __FreeBSD_version >= 1000046
m_clrprotoflags(m);
-#endif
/* NB: see hostap_deliver_data, this path doesn't handle hostap */
KASSERT(vap->iv_opmode != IEEE80211_M_HOSTAP, ("gack, hostap"));
@@ -448,8 +447,9 @@ int
ieee80211_alloc_challenge(struct ieee80211_node *ni)
{
if (ni->ni_challenge == NULL)
- ni->ni_challenge = (uint32_t *) malloc(IEEE80211_CHALLENGE_LEN,
- M_80211_NODE, M_NOWAIT);
+ ni->ni_challenge = (uint32_t *)
+ IEEE80211_MALLOC(IEEE80211_CHALLENGE_LEN,
+ M_80211_NODE, IEEE80211_M_NOWAIT);
if (ni->ni_challenge == NULL) {
IEEE80211_NOTE(ni->ni_vap,
IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH, ni,
@@ -468,7 +468,7 @@ ieee80211_alloc_challenge(struct ieee80211_node *ni)
*/
int
ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m,
- struct ieee80211_scanparams *scan)
+ struct ieee80211_channel *rxchan, struct ieee80211_scanparams *scan)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -505,7 +505,7 @@ ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m,
scan->tstamp = frm; frm += 8;
scan->bintval = le16toh(*(uint16_t *)frm); frm += 2;
scan->capinfo = le16toh(*(uint16_t *)frm); frm += 2;
- scan->bchan = ieee80211_chan2ieee(ic, ic->ic_curchan);
+ scan->bchan = ieee80211_chan2ieee(ic, rxchan);
scan->chan = scan->bchan;
scan->ies = frm;
scan->ies_len = efrm - frm;
@@ -648,7 +648,8 @@ ieee80211_parse_beacon(struct ieee80211_node *ni, struct mbuf *m,
*/
IEEE80211_DISCARD(vap,
IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
- wh, NULL, "for off-channel %u", scan->chan);
+ wh, NULL, "for off-channel %u (bchan=%u)",
+ scan->chan, scan->bchan);
vap->iv_stats.is_rx_chanmismatch++;
scan->status |= IEEE80211_BPARSE_OFFCHAN;
}
diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h
index f3d569efd582..72fd25b4ffc9 100644
--- a/sys/net80211/ieee80211_input.h
+++ b/sys/net80211/ieee80211_input.h
@@ -255,6 +255,7 @@ void ieee80211_send_error(struct ieee80211_node *,
const uint8_t mac[IEEE80211_ADDR_LEN], int subtype, int arg);
int ieee80211_alloc_challenge(struct ieee80211_node *);
int ieee80211_parse_beacon(struct ieee80211_node *, struct mbuf *,
+ struct ieee80211_channel *,
struct ieee80211_scanparams *);
int ieee80211_parse_action(struct ieee80211_node *, struct mbuf *);
#endif /* _NET80211_IEEE80211_INPUT_H_ */
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 2798d8089b89..54ab39072ecc 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -323,14 +323,15 @@ ieee80211_ioctl_getscanresults(struct ieee80211vap *vap,
space = req.space;
/* XXX M_WAITOK after driver lock released */
- p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO);
+ p = IEEE80211_MALLOC(space, M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (p == NULL)
return ENOMEM;
req.sr = p;
ieee80211_scan_iterate(vap, get_scan_result, &req);
ireq->i_len = space - req.space;
error = copyout(p, ireq->i_data, ireq->i_len);
- free(p, M_TEMP);
+ IEEE80211_FREE(p, M_TEMP);
} else
ireq->i_len = 0;
@@ -473,7 +474,8 @@ getstainfo_common(struct ieee80211vap *vap, struct ieee80211req *ireq,
if (req.space > 0) {
space = req.space;
/* XXX M_WAITOK after driver lock released */
- p = malloc(space, M_TEMP, M_NOWAIT | M_ZERO);
+ p = IEEE80211_MALLOC(space, M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (p == NULL) {
error = ENOMEM;
goto bad;
@@ -485,7 +487,7 @@ getstainfo_common(struct ieee80211vap *vap, struct ieee80211req *ireq,
get_sta_info(&req, ni);
ireq->i_len = space - req.space;
error = copyout(p, (uint8_t *) ireq->i_data+off, ireq->i_len);
- free(p, M_TEMP);
+ IEEE80211_FREE(p, M_TEMP);
} else
ireq->i_len = 0;
bad:
@@ -697,7 +699,8 @@ ieee80211_ioctl_getdevcaps(struct ieee80211com *ic,
if (maxchans > 2048)
maxchans = 2048;
dc = (struct ieee80211_devcaps_req *)
- malloc(IEEE80211_DEVCAPS_SIZE(maxchans), M_TEMP, M_NOWAIT | M_ZERO);
+ IEEE80211_MALLOC(IEEE80211_DEVCAPS_SIZE(maxchans), M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (dc == NULL)
return ENOMEM;
dc->dc_drivercaps = ic->ic_caps;
@@ -709,7 +712,7 @@ ieee80211_ioctl_getdevcaps(struct ieee80211com *ic,
("nchans %d maxchans %d", ci->ic_nchans, maxchans));
ieee80211_sort_channels(ci->ic_chans, ci->ic_nchans);
error = copyout(dc, ireq->i_data, IEEE80211_DEVCAPS_SPACE(dc));
- free(dc, M_TEMP);
+ IEEE80211_FREE(dc, M_TEMP);
return error;
}
@@ -1666,13 +1669,13 @@ ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
if (ireq->i_len > sizeof(ic->ic_chan_active))
ireq->i_len = sizeof(ic->ic_chan_active);
- list = malloc(ireq->i_len + IEEE80211_CHAN_BYTES, M_TEMP,
- M_NOWAIT | M_ZERO);
+ list = IEEE80211_MALLOC(ireq->i_len + IEEE80211_CHAN_BYTES, M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (list == NULL)
return ENOMEM;
error = copyin(ireq->i_data, list, ireq->i_len);
if (error) {
- free(list, M_TEMP);
+ IEEE80211_FREE(list, M_TEMP);
return error;
}
nchan = 0;
@@ -1691,7 +1694,7 @@ ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
}
}
if (nchan == 0) {
- free(list, M_TEMP);
+ IEEE80211_FREE(list, M_TEMP);
return EINVAL;
}
if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */
@@ -1699,7 +1702,7 @@ ieee80211_ioctl_setchanlist(struct ieee80211vap *vap, struct ieee80211req *ireq)
ic->ic_bsschan = IEEE80211_CHAN_ANYC;
memcpy(ic->ic_chan_active, chanlist, IEEE80211_CHAN_BYTES);
ieee80211_scan_flush(vap);
- free(list, M_TEMP);
+ IEEE80211_FREE(list, M_TEMP);
return ENETRESET;
}
@@ -2112,7 +2115,8 @@ ieee80211_ioctl_setregdomain(struct ieee80211vap *vap,
return EINVAL;
}
reg = (struct ieee80211_regdomain_req *)
- malloc(IEEE80211_REGDOMAIN_SIZE(nchans), M_TEMP, M_NOWAIT);
+ IEEE80211_MALLOC(IEEE80211_REGDOMAIN_SIZE(nchans), M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (reg == NULL) {
IEEE80211_DPRINTF(vap, IEEE80211_MSG_IOCTL,
"%s: no memory, nchans %d\n", __func__, nchans);
@@ -2129,7 +2133,7 @@ ieee80211_ioctl_setregdomain(struct ieee80211vap *vap,
} else
error = ieee80211_setregdomain(vap, reg);
}
- free(reg, M_TEMP);
+ IEEE80211_FREE(reg, M_TEMP);
return (error == 0 ? ENETRESET : error);
}
@@ -2246,7 +2250,7 @@ setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq)
if (ireq->i_len == 0) { /* delete any existing ie */
if (app != NULL) {
*aie = NULL; /* XXX racey */
- free(app, M_80211_NODE_IE);
+ IEEE80211_FREE(app, M_80211_NODE_IE);
}
return 0;
}
@@ -2260,20 +2264,21 @@ setappie(struct ieee80211_appie **aie, const struct ieee80211req *ireq)
*
* XXX bad bad bad
*/
- napp = (struct ieee80211_appie *) malloc(
- sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE, M_NOWAIT);
+ napp = (struct ieee80211_appie *) IEEE80211_MALLOC(
+ sizeof(struct ieee80211_appie) + ireq->i_len, M_80211_NODE_IE,
+ IEEE80211_M_NOWAIT);
if (napp == NULL)
return ENOMEM;
/* XXX holding ic lock */
error = copyin(ireq->i_data, napp->ie_data, ireq->i_len);
if (error) {
- free(napp, M_80211_NODE_IE);
+ IEEE80211_FREE(napp, M_80211_NODE_IE);
return error;
}
napp->ie_len = ireq->i_len;
*aie = napp;
if (app != NULL)
- free(app, M_80211_NODE_IE);
+ IEEE80211_FREE(app, M_80211_NODE_IE);
return 0;
}
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 5ffd50bc7ade..ef811845fc91 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -85,9 +85,10 @@ static void mesh_transmit_to_gate(struct ieee80211vap *, struct mbuf *,
struct ieee80211_mesh_route *);
static void mesh_forward(struct ieee80211vap *, struct mbuf *,
const struct ieee80211_meshcntl *);
-static int mesh_input(struct ieee80211_node *, struct mbuf *, int, int);
+static int mesh_input(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_rx_stats *rxs, int, int);
static void mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
- int, int);
+ const struct ieee80211_rx_stats *rxs, int, int);
static void mesh_recv_ctl(struct ieee80211_node *, struct mbuf *, int);
static void mesh_peer_timeout_setup(struct ieee80211_node *);
static void mesh_peer_timeout_backoff(struct ieee80211_node *);
@@ -161,14 +162,6 @@ static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = {
static struct ieee80211_mesh_proto_path mesh_proto_paths[4];
static struct ieee80211_mesh_proto_metric mesh_proto_metrics[4];
-#define RT_ENTRY_LOCK(rt) mtx_lock(&(rt)->rt_lock)
-#define RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, MA_OWNED)
-#define RT_ENTRY_UNLOCK(rt) mtx_unlock(&(rt)->rt_lock)
-
-#define MESH_RT_LOCK(ms) mtx_lock(&(ms)->ms_rt_lock)
-#define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
-#define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock)
-
MALLOC_DEFINE(M_80211_MESH_PREQ, "80211preq", "802.11 MESH Path Request frame");
MALLOC_DEFINE(M_80211_MESH_PREP, "80211prep", "802.11 MESH Path Reply frame");
MALLOC_DEFINE(M_80211_MESH_PERR, "80211perr", "802.11 MESH Path Error frame");
@@ -210,13 +203,14 @@ mesh_rt_add_locked(struct ieee80211vap *vap,
MESH_RT_LOCK_ASSERT(ms);
- rt = malloc(ALIGN(sizeof(struct ieee80211_mesh_route)) +
- ms->ms_ppath->mpp_privlen, M_80211_MESH_RT, M_NOWAIT | M_ZERO);
+ rt = IEEE80211_MALLOC(ALIGN(sizeof(struct ieee80211_mesh_route)) +
+ ms->ms_ppath->mpp_privlen, M_80211_MESH_RT,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (rt != NULL) {
rt->rt_vap = vap;
IEEE80211_ADDR_COPY(rt->rt_dest, dest);
rt->rt_priv = (void *)ALIGN(&rt[1]);
- mtx_init(&rt->rt_lock, "MBSS_RT", "802.11s route entry", MTX_DEF);
+ MESH_RT_ENTRY_LOCK_INIT(rt, "MBSS_RT");
callout_init(&rt->rt_discovery, 1);
rt->rt_updtime = ticks; /* create time */
TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next);
@@ -269,11 +263,11 @@ ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int new_lifetime)
KASSERT(rt != NULL, ("route is NULL"));
now = ticks;
- RT_ENTRY_LOCK(rt);
+ MESH_RT_ENTRY_LOCK(rt);
/* dont clobber a proxy entry gated by us */
if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY && rt->rt_nhops == 0) {
- RT_ENTRY_UNLOCK(rt);
+ MESH_RT_ENTRY_UNLOCK(rt);
return rt->rt_lifetime;
}
@@ -294,7 +288,7 @@ ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int new_lifetime)
new_lifetime, rt->rt_lifetime);
}
lifetime = rt->rt_lifetime;
- RT_ENTRY_UNLOCK(rt);
+ MESH_RT_ENTRY_UNLOCK(rt);
return lifetime;
}
@@ -356,10 +350,10 @@ mesh_rt_del(struct ieee80211_mesh_state *ms, struct ieee80211_mesh_route *rt)
* Grab the lock before destroying it, to be sure no one else
* is holding the route.
*/
- RT_ENTRY_LOCK(rt);
+ MESH_RT_ENTRY_LOCK(rt);
callout_drain(&rt->rt_discovery);
- mtx_destroy(&rt->rt_lock);
- free(rt, M_80211_MESH_RT);
+ MESH_RT_ENTRY_LOCK_DESTROY(rt);
+ IEEE80211_FREE(rt, M_80211_MESH_RT);
}
void
@@ -651,9 +645,9 @@ mesh_vdetach(struct ieee80211vap *vap)
ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_vdetach_peers,
NULL);
ieee80211_mesh_rt_flush(vap);
- mtx_destroy(&ms->ms_rt_lock);
+ MESH_RT_LOCK_DESTROY(ms);
ms->ms_ppath->mpp_vdetach(vap);
- free(vap->iv_mesh, M_80211_VAP);
+ IEEE80211_FREE(vap->iv_mesh, M_80211_VAP);
vap->iv_mesh = NULL;
}
@@ -666,8 +660,8 @@ mesh_vattach(struct ieee80211vap *vap)
vap->iv_opdetach = mesh_vdetach;
vap->iv_recv_mgmt = mesh_recv_mgmt;
vap->iv_recv_ctl = mesh_recv_ctl;
- ms = malloc(sizeof(struct ieee80211_mesh_state), M_80211_VAP,
- M_NOWAIT | M_ZERO);
+ ms = IEEE80211_MALLOC(sizeof(struct ieee80211_mesh_state), M_80211_VAP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ms == NULL) {
printf("%s: couldn't alloc MBSS state\n", __func__);
return;
@@ -678,7 +672,7 @@ mesh_vattach(struct ieee80211vap *vap)
ms->ms_ttl = IEEE80211_MESH_DEFAULT_TTL;
TAILQ_INIT(&ms->ms_known_gates);
TAILQ_INIT(&ms->ms_routes);
- mtx_init(&ms->ms_rt_lock, "MBSS", "802.11s routing table", MTX_DEF);
+ MESH_RT_LOCK_INIT(ms, "MBSS");
callout_init(&ms->ms_cleantimer, 1);
callout_init(&ms->ms_gatetimer, 1);
ms->ms_gateseq = 0;
@@ -884,8 +878,9 @@ ieee80211_mesh_mark_gate(struct ieee80211vap *vap, const uint8_t *addr,
/* New mesh gate add it to known table. */
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, addr,
"%s", "stored new gate information from pro-PREQ.");
- gr = malloc(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
- M_80211_MESH_GT_RT, M_NOWAIT | M_ZERO);
+ gr = IEEE80211_MALLOC(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
+ M_80211_MESH_GT_RT,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
IEEE80211_ADDR_COPY(gr->gr_addr, addr);
TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next);
}
@@ -1532,7 +1527,8 @@ mesh_recv_group_data(struct ieee80211vap *vap, struct mbuf *m,
}
static int
-mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+mesh_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
#define HAS_SEQ(type) ((type & 0x4) == 0)
#define MC01(mc) ((const struct ieee80211_meshcntl_ae01 *)mc)
@@ -1831,7 +1827,7 @@ mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
goto out;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
vap->iv_stats.is_rx_ctl++;
@@ -1859,11 +1855,12 @@ out:
static void
mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
- int rssi, int nf)
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_channel *rxchan = ic->ic_curchan;
struct ieee80211_frame *wh;
struct ieee80211_mesh_route *rt;
uint8_t *frm, *efrm;
@@ -1876,11 +1873,17 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
case IEEE80211_FC0_SUBTYPE_BEACON:
{
struct ieee80211_scanparams scan;
+ struct ieee80211_channel *c;
/*
* We process beacon/probe response
* frames to discover neighbors.
*/
- if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
+ if (rxs != NULL) {
+ c = ieee80211_lookup_channel_rxstatus(vap, rxs);
+ if (c != NULL)
+ rxchan = c;
+ }
+ if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0)
return;
/*
* Count frame now that we know it's to be processed.
@@ -1906,7 +1909,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
ieee80211_probe_curchan(vap, 1);
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
}
- ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh,
+ ieee80211_add_scan(vap, rxchan, &scan, wh,
subtype, rssi, nf);
return;
}
@@ -2634,8 +2637,9 @@ mesh_recv_action_meshgate(struct ieee80211_node *ni,
/* this GANN is from a new mesh Gate add it to known table. */
IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, ie.gann_addr,
"stored new GANN information, seq %u.", ie.gann_seq);
- gr = malloc(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
- M_80211_MESH_GT_RT, M_NOWAIT | M_ZERO);
+ gr = IEEE80211_MALLOC(ALIGN(sizeof(struct ieee80211_mesh_gate_route)),
+ M_80211_MESH_GT_RT,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
IEEE80211_ADDR_COPY(gr->gr_addr, ie.gann_addr);
TAILQ_INSERT_TAIL(&ms->ms_known_gates, gr, gr_next);
}
@@ -3482,7 +3486,8 @@ mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
}
ireq->i_len = len;
/* XXX M_WAIT? */
- p = malloc(len, M_TEMP, M_NOWAIT | M_ZERO);
+ p = IEEE80211_MALLOC(len, M_TEMP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (p == NULL)
return ENOMEM;
off = 0;
@@ -3507,7 +3512,7 @@ mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
MESH_RT_UNLOCK(ms);
error = copyout(p, (uint8_t *)ireq->i_data,
ireq->i_len);
- free(p, M_TEMP);
+ IEEE80211_FREE(p, M_TEMP);
break;
case IEEE80211_MESH_RTCMD_FLUSH:
case IEEE80211_MESH_RTCMD_ADD:
diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h
index 5dc2b2c12b17..2253af0060a4 100644
--- a/sys/net80211/ieee80211_mesh.h
+++ b/sys/net80211/ieee80211_mesh.h
@@ -418,7 +418,7 @@ MALLOC_DECLARE(M_80211_MESH_GT_RT);
struct ieee80211_mesh_route {
TAILQ_ENTRY(ieee80211_mesh_route) rt_next;
struct ieee80211vap *rt_vap;
- struct mtx rt_lock; /* fine grained route lock */
+ ieee80211_rte_lock_t rt_lock; /* fine grained route lock */
struct callout rt_discovery; /* discovery timeout */
int rt_updtime; /* last update time */
uint8_t rt_dest[IEEE80211_ADDR_LEN];
@@ -515,7 +515,7 @@ struct ieee80211_mesh_state {
#define IEEE80211_MESHFLAGS_FWD 0x04 /* forward packets */
#define IEEE80211_MESHFLAGS_ROOT 0x08 /* configured as root */
uint8_t ms_flags;
- struct mtx ms_rt_lock;
+ ieee80211_rt_lock_t ms_rt_lock;
struct callout ms_cleantimer;
struct callout ms_gatetimer;
ieee80211_mesh_seq ms_gateseq;
diff --git a/sys/net80211/ieee80211_monitor.c b/sys/net80211/ieee80211_monitor.c
index 8909339bde29..e0778461fd42 100644
--- a/sys/net80211/ieee80211_monitor.c
+++ b/sys/net80211/ieee80211_monitor.c
@@ -61,7 +61,7 @@ __FBSDID("$FreeBSD$");
static void monitor_vattach(struct ieee80211vap *);
static int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static int monitor_input(struct ieee80211_node *ni, struct mbuf *m,
- int rssi, int nf);
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf);
void
ieee80211_monitor_attach(struct ieee80211com *ic)
@@ -125,7 +125,8 @@ monitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* Process a received frame in monitor mode.
*/
static int
-monitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+monitor_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ifnet *ifp = vap->iv_ifp;
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index fbb8e9343125..82cfccfaee79 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -172,9 +172,10 @@ ieee80211_node_latevattach(struct ieee80211vap *vap)
"WARNING: max aid too small, changed to %d\n",
vap->iv_max_aid);
}
- vap->iv_aid_bitmap = (uint32_t *) malloc(
+ vap->iv_aid_bitmap = (uint32_t *) IEEE80211_MALLOC(
howmany(vap->iv_max_aid, 32) * sizeof(uint32_t),
- M_80211_NODE, M_NOWAIT | M_ZERO);
+ M_80211_NODE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (vap->iv_aid_bitmap == NULL) {
/* XXX no way to recover */
printf("%s: no memory for AID bitmap, max aid %d!\n",
@@ -199,7 +200,7 @@ ieee80211_node_vdetach(struct ieee80211vap *vap)
vap->iv_bss = NULL;
}
if (vap->iv_aid_bitmap != NULL) {
- free(vap->iv_aid_bitmap, M_80211_NODE);
+ IEEE80211_FREE(vap->iv_aid_bitmap, M_80211_NODE);
vap->iv_aid_bitmap = NULL;
}
}
@@ -892,8 +893,8 @@ node_alloc(struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN])
{
struct ieee80211_node *ni;
- ni = (struct ieee80211_node *) malloc(sizeof(struct ieee80211_node),
- M_80211_NODE, M_NOWAIT | M_ZERO);
+ ni = (struct ieee80211_node *) IEEE80211_MALLOC(sizeof(struct ieee80211_node),
+ M_80211_NODE, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
return ni;
}
@@ -910,11 +911,12 @@ ieee80211_ies_init(struct ieee80211_ies *ies, const uint8_t *data, int len)
memset(ies, 0, offsetof(struct ieee80211_ies, data));
if (ies->data != NULL && ies->len != len) {
/* data size changed */
- free(ies->data, M_80211_NODE_IE);
+ IEEE80211_FREE(ies->data, M_80211_NODE_IE);
ies->data = NULL;
}
if (ies->data == NULL) {
- ies->data = (uint8_t *) malloc(len, M_80211_NODE_IE, M_NOWAIT);
+ ies->data = (uint8_t *) IEEE80211_MALLOC(len, M_80211_NODE_IE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ies->data == NULL) {
ies->len = 0;
/* NB: pointers have already been zero'd above */
@@ -933,7 +935,7 @@ void
ieee80211_ies_cleanup(struct ieee80211_ies *ies)
{
if (ies->data != NULL)
- free(ies->data, M_80211_NODE_IE);
+ IEEE80211_FREE(ies->data, M_80211_NODE_IE);
}
/*
@@ -1045,7 +1047,7 @@ node_cleanup(struct ieee80211_node *ni)
ni->ni_associd = 0;
if (ni->ni_challenge != NULL) {
- free(ni->ni_challenge, M_80211_NODE);
+ IEEE80211_FREE(ni->ni_challenge, M_80211_NODE);
ni->ni_challenge = NULL;
}
/*
@@ -1080,7 +1082,7 @@ node_free(struct ieee80211_node *ni)
ic->ic_node_cleanup(ni);
ieee80211_ies_cleanup(&ni->ni_ies);
ieee80211_psq_cleanup(&ni->ni_psq);
- free(ni, M_80211_NODE);
+ IEEE80211_FREE(ni, M_80211_NODE);
}
static void
@@ -1908,22 +1910,22 @@ ieee80211_node_table_init(struct ieee80211com *ic,
struct ieee80211_node_table *nt,
const char *name, int inact, int keyixmax)
{
- struct ifnet *ifp = ic->ic_ifp;
nt->nt_ic = ic;
- IEEE80211_NODE_LOCK_INIT(nt, ifp->if_xname);
- IEEE80211_NODE_ITERATE_LOCK_INIT(nt, ifp->if_xname);
+ IEEE80211_NODE_LOCK_INIT(nt, ic->ic_name);
+ IEEE80211_NODE_ITERATE_LOCK_INIT(nt, ic->ic_name);
TAILQ_INIT(&nt->nt_node);
nt->nt_name = name;
nt->nt_scangen = 1;
nt->nt_inact_init = inact;
nt->nt_keyixmax = keyixmax;
if (nt->nt_keyixmax > 0) {
- nt->nt_keyixmap = (struct ieee80211_node **) malloc(
+ nt->nt_keyixmap = (struct ieee80211_node **) IEEE80211_MALLOC(
keyixmax * sizeof(struct ieee80211_node *),
- M_80211_NODE, M_NOWAIT | M_ZERO);
+ M_80211_NODE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (nt->nt_keyixmap == NULL)
- if_printf(ic->ic_ifp,
+ ic_printf(ic,
"Cannot allocate key index map with %u entries\n",
keyixmax);
} else
@@ -1980,7 +1982,7 @@ ieee80211_node_table_cleanup(struct ieee80211_node_table *nt)
printf("%s: %s[%u] still active\n", __func__,
nt->nt_name, i);
#endif
- free(nt->nt_keyixmap, M_80211_NODE);
+ IEEE80211_FREE(nt->nt_keyixmap, M_80211_NODE);
nt->nt_keyixmap = NULL;
}
IEEE80211_NODE_ITERATE_LOCK_DESTROY(nt);
@@ -2256,8 +2258,8 @@ ieee80211_iterate_nt(struct ieee80211_node_table *nt,
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
if (i >= max_aid) {
ret = E2BIG;
- if_printf(nt->nt_ic->ic_ifp,
- "Node array overflow: max=%u", max_aid);
+ ic_printf(nt->nt_ic, "Node array overflow: max=%u",
+ max_aid);
break;
}
ni_arr[i] = ieee80211_ref_node(ni);
@@ -2319,8 +2321,8 @@ ieee80211_iterate_nodes(struct ieee80211_node_table *nt,
max_aid = vap->iv_max_aid;
size = max_aid * sizeof(struct ieee80211_node *);
- ni_arr = (struct ieee80211_node **) malloc(size, M_80211_NODE,
- M_NOWAIT | M_ZERO);
+ ni_arr = (struct ieee80211_node **) IEEE80211_MALLOC(size, M_80211_NODE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ni_arr == NULL)
return;
@@ -2343,7 +2345,7 @@ ieee80211_iterate_nodes(struct ieee80211_node_table *nt,
}
done:
- free(ni_arr, M_80211_NODE);
+ IEEE80211_FREE(ni_arr, M_80211_NODE);
}
void
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 2158bee56ca0..d11628df04ac 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -508,6 +508,26 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,
{
struct ieee80211com *ic = vap->iv_ic;
+ /*
+ * Set node - the caller has taken a reference, so ensure
+ * that the mbuf has the same node value that
+ * it would if it were going via the normal path.
+ */
+ m->m_pkthdr.rcvif = (void *)ni;
+
+ /*
+ * Attempt to add bpf transmit parameters.
+ *
+ * For now it's ok to fail; the raw_xmit api still takes
+ * them as an option.
+ *
+ * Later on when ic_raw_xmit() has params removed,
+ * they'll have to be added - so fail the transmit if
+ * they can't be.
+ */
+ if (params)
+ (void) ieee80211_add_xmit_params(m, params);
+
return (ic->ic_raw_xmit(ni, m, params));
}
@@ -516,15 +536,9 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,
* connect bpf write calls to the 802.11 layer for injecting
* raw 802.11 frames.
*/
-#if __FreeBSD_version >= 1000031
int
ieee80211_output(struct ifnet *ifp, struct mbuf *m,
const struct sockaddr *dst, struct route *ro)
-#else
-int
-ieee80211_output(struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *dst, struct route *ro)
-#endif
{
#define senderr(e) do { error = (e); goto bad;} while (0)
struct ieee80211_node *ni = NULL;
@@ -1950,7 +1964,7 @@ ieee80211_add_countryie(uint8_t *frm, struct ieee80211com *ic)
* re-calculation.
*/
if (ic->ic_countryie != NULL)
- free(ic->ic_countryie, M_80211_NODE_IE);
+ IEEE80211_FREE(ic->ic_countryie, M_80211_NODE_IE);
ic->ic_countryie = ieee80211_alloc_countryie(ic);
if (ic->ic_countryie == NULL)
return frm;
diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c
index 812cd7053ce9..91668cc7c0d2 100644
--- a/sys/net80211/ieee80211_power.c
+++ b/sys/net80211/ieee80211_power.c
@@ -83,8 +83,9 @@ ieee80211_power_latevattach(struct ieee80211vap *vap)
*/
if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
vap->iv_tim_len = howmany(vap->iv_max_aid,8) * sizeof(uint8_t);
- vap->iv_tim_bitmap = (uint8_t *) malloc(vap->iv_tim_len,
- M_80211_POWER, M_NOWAIT | M_ZERO);
+ vap->iv_tim_bitmap = (uint8_t *) IEEE80211_MALLOC(vap->iv_tim_len,
+ M_80211_POWER,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (vap->iv_tim_bitmap == NULL) {
printf("%s: no memory for TIM bitmap!\n", __func__);
/* XXX good enough to keep from crashing? */
@@ -97,7 +98,7 @@ void
ieee80211_power_vdetach(struct ieee80211vap *vap)
{
if (vap->iv_tim_bitmap != NULL) {
- free(vap->iv_tim_bitmap, M_80211_POWER);
+ IEEE80211_FREE(vap->iv_tim_bitmap, M_80211_POWER);
vap->iv_tim_bitmap = NULL;
}
}
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 1f096168d927..01c60e1614e5 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -113,9 +113,8 @@ static int
null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = ni->ni_ic->ic_ifp;
- if_printf(ifp, "missing ic_raw_xmit callback, drop frame\n");
+ ic_printf(ni->ni_ic, "missing ic_raw_xmit callback, drop frame\n");
m_freem(m);
return ENETDOWN;
}
@@ -251,7 +250,7 @@ ieee80211_proto_vdetach(struct ieee80211vap *vap)
{
#define FREEAPPIE(ie) do { \
if (ie != NULL) \
- free(ie, M_80211_NODE_IE); \
+ IEEE80211_FREE(ie, M_80211_NODE_IE); \
} while (0)
/*
* Detach operating mode module.
@@ -651,7 +650,7 @@ ieee80211_set_shortslottime(struct ieee80211com *ic, int onoff)
ic->ic_flags &= ~IEEE80211_F_SHSLOT;
/* notify driver */
if (ic->ic_updateslot != NULL)
- ic->ic_updateslot(ic->ic_ifp);
+ ic->ic_updateslot(ic);
}
/*
@@ -1165,18 +1164,16 @@ static void
update_mcast(void *arg, int npending)
{
struct ieee80211com *ic = arg;
- struct ifnet *parent = ic->ic_ifp;
- ic->ic_update_mcast(parent);
+ ic->ic_update_mcast(ic);
}
static void
update_promisc(void *arg, int npending)
{
struct ieee80211com *ic = arg;
- struct ifnet *parent = ic->ic_ifp;
- ic->ic_update_promisc(parent);
+ ic->ic_update_promisc(ic);
}
static void
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 3b46ac4b1ecd..a8123931588f 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -68,6 +68,9 @@ void ieee80211_syncflag_ext(struct ieee80211vap *, int flag);
#define IEEE80211_R_C_RSSI 0x0000010 /* per-chain RSSI value valid */
#define IEEE80211_R_C_EVM 0x0000020 /* per-chain EVM valid */
#define IEEE80211_R_C_HT40 0x0000040 /* RX'ed packet is 40mhz, pilots 4,5 valid */
+#define IEEE80211_R_FREQ 0x0000080 /* Freq value populated, MHz */
+#define IEEE80211_R_IEEE 0x0000100 /* IEEE value populated */
+#define IEEE80211_R_BAND 0x0000200 /* Frequency band populated */
struct ieee80211_rx_stats {
uint32_t r_flags; /* IEEE80211_R_* flags */
@@ -80,10 +83,12 @@ struct ieee80211_rx_stats {
uint8_t rssi; /* global RSSI */
uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
/* per-chain, per-pilot EVM values */
+ uint16_t c_freq;
+ uint8_t c_ieee;
};
#define ieee80211_input(ni, m, rssi, nf) \
- ((ni)->ni_vap->iv_input(ni, m, rssi, nf))
+ ((ni)->ni_vap->iv_input(ni, m, NULL, rssi, nf))
int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int);
int ieee80211_input_mimo(struct ieee80211_node *, struct mbuf *,
@@ -96,13 +101,8 @@ int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int,
struct ieee80211_bpf_params *);
int ieee80211_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-#if __FreeBSD_version >= 1000031
int ieee80211_output(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *ro);
-#else
-int ieee80211_output(struct ifnet *, struct mbuf *,
- struct sockaddr *, struct route *ro);
-#endif
int ieee80211_vap_pkt_send_dest(struct ieee80211vap *, struct mbuf *,
struct ieee80211_node *);
int ieee80211_raw_output(struct ieee80211vap *, struct ieee80211_node *,
diff --git a/sys/net80211/ieee80211_radiotap.c b/sys/net80211/ieee80211_radiotap.c
index 5638f52c2ca9..eb218dd4ffba 100644
--- a/sys/net80211/ieee80211_radiotap.c
+++ b/sys/net80211/ieee80211_radiotap.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <net/bpf.h>
#include <net/if.h>
#include <net/if_var.h>
-#include <net/if_llc.h>
#include <net/if_media.h>
#include <net/ethernet.h>
@@ -80,8 +79,8 @@ ieee80211_radiotap_attachv(struct ieee80211com *ic,
else if (tx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL))
off = radiotap_offset(th, n_tx_v, IEEE80211_RADIOTAP_XCHANNEL);
if (off == -1) {
- if_printf(ic->ic_ifp, "%s: no tx channel, radiotap 0x%x\n",
- __func__, tx_radiotap);
+ ic_printf(ic, "%s: no tx channel, radiotap 0x%x\n", __func__,
+ tx_radiotap);
/* NB: we handle this case but data will have no chan spec */
} else
ic->ic_txchan = ((uint8_t *) th) + off;
@@ -96,8 +95,8 @@ ieee80211_radiotap_attachv(struct ieee80211com *ic,
else if (rx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL))
off = radiotap_offset(rh, n_rx_v, IEEE80211_RADIOTAP_XCHANNEL);
if (off == -1) {
- if_printf(ic->ic_ifp, "%s: no rx channel, radiotap 0x%x\n",
- __func__, rx_radiotap);
+ ic_printf(ic, "%s: no rx channel, radiotap 0x%x\n", __func__,
+ rx_radiotap);
/* NB: we handle this case but data will have no chan spec */
} else
ic->ic_rxchan = ((uint8_t *) rh) + off;
diff --git a/sys/net80211/ieee80211_ratectl_none.c b/sys/net80211/ieee80211_ratectl_none.c
index a0056f3f5355..5a45a74ea7a3 100644
--- a/sys/net80211/ieee80211_ratectl_none.c
+++ b/sys/net80211/ieee80211_ratectl_none.c
@@ -56,7 +56,7 @@ none_init(struct ieee80211vap *vap)
static void
none_deinit(struct ieee80211vap *vap)
{
- free(vap->iv_rs, M_80211_RATECTL);
+ IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL);
}
static void
diff --git a/sys/net80211/ieee80211_regdomain.c b/sys/net80211/ieee80211_regdomain.c
index ed7f4227ef53..9dfef2c5f168 100644
--- a/sys/net80211/ieee80211_regdomain.c
+++ b/sys/net80211/ieee80211_regdomain.c
@@ -84,7 +84,7 @@ void
ieee80211_regdomain_detach(struct ieee80211com *ic)
{
if (ic->ic_countryie != NULL) {
- free(ic->ic_countryie, M_80211_NODE_IE);
+ IEEE80211_FREE(ic->ic_countryie, M_80211_NODE_IE);
ic->ic_countryie = NULL;
}
}
@@ -301,19 +301,19 @@ ieee80211_alloc_countryie(struct ieee80211com *ic)
struct ieee80211_country_ie *ie;
int i, skip, nruns;
- aie = malloc(IEEE80211_COUNTRY_MAX_SIZE, M_80211_NODE_IE,
- M_NOWAIT | M_ZERO);
+ aie = IEEE80211_MALLOC(IEEE80211_COUNTRY_MAX_SIZE, M_80211_NODE_IE,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (aie == NULL) {
- if_printf(ic->ic_ifp,
- "%s: unable to allocate memory for country ie\n", __func__);
+ ic_printf(ic, "%s: unable to allocate memory for country ie\n",
+ __func__);
/* XXX stat */
return NULL;
}
ie = (struct ieee80211_country_ie *) aie->ie_data;
ie->ie = IEEE80211_ELEMID_COUNTRY;
if (rd->isocc[0] == '\0') {
- if_printf(ic->ic_ifp, "no ISO country string for cc %d; "
- "using blanks\n", rd->country);
+ ic_printf(ic, "no ISO country string for cc %d; using blanks\n",
+ rd->country);
ie->cc[0] = ie->cc[1] = ' ';
} else {
ie->cc[0] = rd->isocc[0];
@@ -350,7 +350,7 @@ ieee80211_alloc_countryie(struct ieee80211com *ic)
if (c->ic_ieee != nextchan ||
c->ic_maxregpower != frm[-1]) { /* new run */
if (nruns == IEEE80211_COUNTRY_MAX_BANDS) {
- if_printf(ic->ic_ifp, "%s: country ie too big, "
+ ic_printf(ic, "%s: country ie too big, "
"runs > max %d, truncating\n",
__func__, IEEE80211_COUNTRY_MAX_BANDS);
/* XXX stat? fail? */
@@ -493,7 +493,7 @@ ieee80211_setregdomain(struct ieee80211vap *vap,
* Invalidate channel-related state.
*/
if (ic->ic_countryie != NULL) {
- free(ic->ic_countryie, M_80211_NODE_IE);
+ IEEE80211_FREE(ic->ic_countryie, M_80211_NODE_IE);
ic->ic_countryie = NULL;
}
ieee80211_scan_flush(vap);
diff --git a/sys/net80211/ieee80211_rssadapt.c b/sys/net80211/ieee80211_rssadapt.c
index f230f60d8f4f..b5fdb86b69b4 100644
--- a/sys/net80211/ieee80211_rssadapt.c
+++ b/sys/net80211/ieee80211_rssadapt.c
@@ -132,8 +132,8 @@ rssadapt_init(struct ieee80211vap *vap)
KASSERT(vap->iv_rs == NULL, ("%s: iv_rs already initialized",
__func__));
- vap->iv_rs = rs = malloc(sizeof(struct ieee80211_rssadapt),
- M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ vap->iv_rs = rs = IEEE80211_MALLOC(sizeof(struct ieee80211_rssadapt),
+ M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (rs == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n");
return;
@@ -146,7 +146,7 @@ rssadapt_init(struct ieee80211vap *vap)
static void
rssadapt_deinit(struct ieee80211vap *vap)
{
- free(vap->iv_rs, M_80211_RATECTL);
+ IEEE80211_FREE(vap->iv_rs, M_80211_RATECTL);
}
static void
@@ -175,8 +175,8 @@ rssadapt_node_init(struct ieee80211_node *ni)
if (ni->ni_rctls == NULL) {
ni->ni_rctls = ra =
- malloc(sizeof(struct ieee80211_rssadapt_node),
- M_80211_RATECTL, M_NOWAIT|M_ZERO);
+ IEEE80211_MALLOC(sizeof(struct ieee80211_rssadapt_node),
+ M_80211_RATECTL, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ra == NULL) {
if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl "
"structure\n");
@@ -204,7 +204,7 @@ static void
rssadapt_node_deinit(struct ieee80211_node *ni)
{
- free(ni->ni_rctls, M_80211_RATECTL);
+ IEEE80211_FREE(ni->ni_rctls, M_80211_RATECTL);
}
static __inline int
diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c
index 6c950d6bc88d..f28a9829d60d 100644
--- a/sys/net80211/ieee80211_scan.c
+++ b/sys/net80211/ieee80211_scan.c
@@ -71,15 +71,14 @@ __FBSDID("$FreeBSD$");
void
ieee80211_scan_attach(struct ieee80211com *ic)
{
-
/*
- * For now, the swscan module does both the
- * allocation (so it can pad it) and sets up the net80211
- * bits.
- *
- * I'll split this stuff later.
+ * If there's no scan method pointer, attach the
+ * swscan set as a default.
*/
- ieee80211_swscan_attach(ic);
+ if (ic->ic_scan_methods == NULL)
+ ieee80211_swscan_attach(ic);
+ else
+ ic->ic_scan_methods->sc_attach(ic);
}
void
@@ -88,12 +87,11 @@ ieee80211_scan_detach(struct ieee80211com *ic)
/*
* Ideally we'd do the ss_ops detach call here;
- * but then ieee80211_swscan_detach would need
- * to be split in two.
+ * but then sc_detach() would need to be split in two.
*
* I'll do that later.
*/
- ieee80211_swscan_detach(ic);
+ ic->ic_scan_methods->sc_detach(ic);
}
static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = {
@@ -122,6 +120,8 @@ static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = {
void
ieee80211_scan_vattach(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
+
vap->iv_bgscanidle = (IEEE80211_BGSCAN_IDLE_DEFAULT*1000)/hz;
vap->iv_bgscanintvl = IEEE80211_BGSCAN_INTVAL_DEFAULT*hz;
vap->iv_scanvalid = IEEE80211_SCAN_VALID_DEFAULT*hz;
@@ -129,7 +129,7 @@ ieee80211_scan_vattach(struct ieee80211vap *vap)
vap->iv_roaming = IEEE80211_ROAMING_AUTO;
memcpy(vap->iv_roamparms, defroam, sizeof(defroam));
- ieee80211_swscan_vattach(vap);
+ ic->ic_scan_methods->sc_vattach(vap);
}
void
@@ -141,7 +141,7 @@ ieee80211_scan_vdetach(struct ieee80211vap *vap)
IEEE80211_LOCK(ic);
ss = ic->ic_scan;
- ieee80211_swscan_vdetach(vap);
+ ic->ic_scan_methods->sc_vdetach(vap);
if (ss != NULL && ss->ss_vap == vap) {
if (ss->ss_ops != NULL) {
@@ -314,6 +314,7 @@ ieee80211_start_scan(struct ieee80211vap *vap, int flags,
u_int nssid, const struct ieee80211_scan_ssid ssids[])
{
const struct ieee80211_scanner *scan;
+ struct ieee80211com *ic = vap->iv_ic;
scan = ieee80211_scanner_get(vap->iv_opmode);
if (scan == NULL) {
@@ -324,8 +325,7 @@ ieee80211_start_scan(struct ieee80211vap *vap, int flags,
return 0;
}
- /* XXX ops */
- return ieee80211_swscan_start_scan(scan, vap, flags, duration,
+ return ic->ic_scan_methods->sc_start_scan(scan, vap, flags, duration,
mindwell, maxdwell, nssid, ssids);
}
@@ -376,11 +376,10 @@ ieee80211_check_scan(struct ieee80211vap *vap, int flags,
/*
* XXX TODO: separate things out a bit better.
- * XXX TODO: ops
*/
ieee80211_scan_update_locked(vap, scan);
- result = ieee80211_swscan_check_scan(scan, vap, flags, duration,
+ result = ic->ic_scan_methods->sc_check_scan(scan, vap, flags, duration,
mindwell, maxdwell, nssid, ssids);
IEEE80211_UNLOCK(ic);
@@ -408,6 +407,7 @@ ieee80211_check_scan_current(struct ieee80211vap *vap)
int
ieee80211_bg_scan(struct ieee80211vap *vap, int flags)
{
+ struct ieee80211com *ic = vap->iv_ic;
const struct ieee80211_scanner *scan;
// IEEE80211_UNLOCK_ASSERT(sc);
@@ -425,10 +425,8 @@ ieee80211_bg_scan(struct ieee80211vap *vap, int flags)
* XXX TODO: pull apart the bgscan logic into whatever
* belongs here and whatever belongs in the software
* scanner.
- *
- * XXX TODO: ops
*/
- return (ieee80211_swscan_bg_scan(scan, vap, flags));
+ return (ic->ic_scan_methods->sc_bg_scan(scan, vap, flags));
}
/*
@@ -437,9 +435,9 @@ ieee80211_bg_scan(struct ieee80211vap *vap, int flags)
void
ieee80211_cancel_scan(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
- /* XXX TODO: ops */
- ieee80211_swscan_cancel_scan(vap);
+ ic->ic_scan_methods->sc_cancel_scan(vap);
}
/*
@@ -448,9 +446,9 @@ ieee80211_cancel_scan(struct ieee80211vap *vap)
void
ieee80211_cancel_anyscan(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
- /* XXX TODO: ops */
- ieee80211_swscan_cancel_anyscan(vap);
+ ic->ic_scan_methods->sc_cancel_anyscan(vap);
}
/*
@@ -460,9 +458,9 @@ ieee80211_cancel_anyscan(struct ieee80211vap *vap)
void
ieee80211_scan_next(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
- /* XXX TODO: ops */
- ieee80211_swscan_scan_next(vap);
+ ic->ic_scan_methods->sc_scan_next(vap);
}
/*
@@ -481,8 +479,7 @@ ieee80211_scan_done(struct ieee80211vap *vap)
ss = ic->ic_scan;
ss->ss_next = ss->ss_last; /* all channels are complete */
- /* XXX TODO: ops */
- ieee80211_swscan_scan_done(vap);
+ ic->ic_scan_methods->sc_scan_done(vap);
IEEE80211_UNLOCK(ic);
}
@@ -504,8 +501,7 @@ ieee80211_probe_curchan(struct ieee80211vap *vap, int force)
return;
}
- /* XXX TODO: ops */
- ieee80211_swscan_probe_curchan(vap, force);
+ ic->ic_scan_methods->sc_scan_probe_curchan(vap, force);
}
#ifdef IEEE80211_DEBUG
@@ -567,8 +563,9 @@ ieee80211_add_scan(struct ieee80211vap *vap,
const struct ieee80211_frame *wh,
int subtype, int rssi, int noise)
{
+ struct ieee80211com *ic = vap->iv_ic;
- return (ieee80211_swscan_add_scan(vap, curchan, sp, wh, subtype,
+ return (ic->ic_scan_methods->sc_add_scan(vap, curchan, sp, wh, subtype,
rssi, noise));
}
diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h
index 8b54186af517..f568b651151c 100644
--- a/sys/net80211/ieee80211_scan.h
+++ b/sys/net80211/ieee80211_scan.h
@@ -80,6 +80,39 @@ struct ieee80211_scan_ssid {
#define IEEE80211_SCAN_MAX_SSID 1 /* max # ssid's to probe */
/*
+ * High-level implementation visible to ieee80211_scan.[ch].
+ *
+ * The default scanner (ieee80211_scan_sw.[ch]) implements a software
+ * driven scanner. Firmware driven scanning needs a different set of
+ * behaviours.
+ */
+struct ieee80211_scan_methods {
+ void (*sc_attach)(struct ieee80211com *);
+ void (*sc_detach)(struct ieee80211com *);
+ void (*sc_vattach)(struct ieee80211vap *);
+ void (*sc_vdetach)(struct ieee80211vap *);
+ void (*sc_set_scan_duration)(struct ieee80211vap *, u_int);
+ int (*sc_start_scan)(const struct ieee80211_scanner *,
+ struct ieee80211vap *, int, u_int, u_int, u_int, u_int,
+ const struct ieee80211_scan_ssid ssids[]);
+ int (*sc_check_scan)(const struct ieee80211_scanner *,
+ struct ieee80211vap *, int, u_int, u_int, u_int, u_int,
+ const struct ieee80211_scan_ssid ssids[]);
+ int (*sc_bg_scan)(const struct ieee80211_scanner *,
+ struct ieee80211vap *, int);
+ void (*sc_cancel_scan)(struct ieee80211vap *);
+ void (*sc_cancel_anyscan)(struct ieee80211vap *);
+ void (*sc_scan_next)(struct ieee80211vap *);
+ void (*sc_scan_done)(struct ieee80211vap *);
+ void (*sc_scan_probe_curchan)(struct ieee80211vap *, int);
+ void (*sc_add_scan)(struct ieee80211vap *,
+ struct ieee80211_channel *,
+ const struct ieee80211_scanparams *,
+ const struct ieee80211_frame *,
+ int, int, int);
+};
+
+/*
* Scan state visible to the 802.11 layer. Scan parameters and
* results are stored in this data structure. The ieee80211_scan_state
* structure is extended with space that is maintained private to
diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c
index 1fb45b098e31..c0cbb7d2de4f 100644
--- a/sys/net80211/ieee80211_scan_sta.c
+++ b/sys/net80211/ieee80211_scan_sta.c
@@ -102,7 +102,7 @@ struct sta_table {
ieee80211_scan_table_lock_t st_lock; /* on scan table */
TAILQ_HEAD(, sta_entry) st_entry; /* all entries */
LIST_HEAD(, sta_entry) st_hash[STA_HASHSIZE];
- struct mtx st_scanlock; /* on st_scaniter */
+ ieee80211_scan_iter_lock_t st_scanlock; /* on st_scaniter */
u_int st_scaniter; /* gen# for iterator */
u_int st_scangen; /* scan generation # */
int st_newscan;
@@ -159,12 +159,13 @@ sta_attach(struct ieee80211_scan_state *ss)
{
struct sta_table *st;
- st = (struct sta_table *) malloc(sizeof(struct sta_table),
- M_80211_SCAN, M_NOWAIT | M_ZERO);
+ st = (struct sta_table *) IEEE80211_MALLOC(sizeof(struct sta_table),
+ M_80211_SCAN,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (st == NULL)
return 0;
IEEE80211_SCAN_TABLE_LOCK_INIT(st, "scantable");
- mtx_init(&st->st_scanlock, "scangen", "802.11 scangen", MTX_DEF);
+ IEEE80211_SCAN_ITER_LOCK_INIT(st, "scangen");
TAILQ_INIT(&st->st_entry);
ss->ss_priv = st;
nrefs++; /* NB: we assume caller locking */
@@ -182,8 +183,8 @@ sta_detach(struct ieee80211_scan_state *ss)
if (st != NULL) {
sta_flush_table(st);
IEEE80211_SCAN_TABLE_LOCK_DESTROY(st);
- mtx_destroy(&st->st_scanlock);
- free(st, M_80211_SCAN);
+ IEEE80211_SCAN_ITER_LOCK_DESTROY(st);
+ IEEE80211_FREE(st, M_80211_SCAN);
KASSERT(nrefs > 0, ("imbalanced attach/detach"));
nrefs--; /* NB: we assume caller locking */
}
@@ -217,7 +218,7 @@ sta_flush_table(struct sta_table *st)
TAILQ_REMOVE(&st->st_entry, se, se_list);
LIST_REMOVE(se, se_hash);
ieee80211_ies_cleanup(&se->base.se_ies);
- free(se, M_80211_SCAN);
+ IEEE80211_FREE(se, M_80211_SCAN);
}
memset(st->st_maxrssi, 0, sizeof(st->st_maxrssi));
}
@@ -252,8 +253,8 @@ sta_add(struct ieee80211_scan_state *ss,
LIST_FOREACH(se, &st->st_hash[hash], se_hash)
if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
goto found;
- se = (struct sta_entry *) malloc(sizeof(struct sta_entry),
- M_80211_SCAN, M_NOWAIT | M_ZERO);
+ se = (struct sta_entry *) IEEE80211_MALLOC(sizeof(struct sta_entry),
+ M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (se == NULL) {
IEEE80211_SCAN_TABLE_UNLOCK(st);
return 0;
@@ -1402,7 +1403,7 @@ sta_iterate(struct ieee80211_scan_state *ss,
struct sta_entry *se;
u_int gen;
- mtx_lock(&st->st_scanlock);
+ IEEE80211_SCAN_ITER_LOCK(st);
gen = st->st_scaniter++;
restart:
IEEE80211_SCAN_TABLE_LOCK(st);
@@ -1418,7 +1419,7 @@ restart:
}
IEEE80211_SCAN_TABLE_UNLOCK(st);
- mtx_unlock(&st->st_scanlock);
+ IEEE80211_SCAN_ITER_UNLOCK(st);
}
static void
@@ -1680,7 +1681,7 @@ adhoc_age(struct ieee80211_scan_state *ss)
TAILQ_REMOVE(&st->st_entry, se, se_list);
LIST_REMOVE(se, se_hash);
ieee80211_ies_cleanup(&se->base.se_ies);
- free(se, M_80211_SCAN);
+ IEEE80211_FREE(se, M_80211_SCAN);
}
}
IEEE80211_SCAN_TABLE_UNLOCK(st);
diff --git a/sys/net80211/ieee80211_scan_sw.c b/sys/net80211/ieee80211_scan_sw.c
index 70b4673294f9..eb58386fc907 100644
--- a/sys/net80211/ieee80211_scan_sw.c
+++ b/sys/net80211/ieee80211_scan_sw.c
@@ -102,33 +102,7 @@ static void scan_task(void *, int);
MALLOC_DEFINE(M_80211_SCAN, "80211scan", "802.11 scan state");
-void
-ieee80211_swscan_attach(struct ieee80211com *ic)
-{
- struct scan_state *ss;
-
- ss = (struct scan_state *) malloc(sizeof(struct scan_state),
- M_80211_SCAN, M_NOWAIT | M_ZERO);
- if (ss == NULL) {
- ic->ic_scan = NULL;
- return;
- }
- callout_init_mtx(&ss->ss_scan_timer, IEEE80211_LOCK_OBJ(ic), 0);
- cv_init(&ss->ss_scan_cv, "scan");
- TASK_INIT(&ss->ss_scan_task, 0, scan_task, ss);
-
- ic->ic_scan = &ss->base;
- ss->base.ss_ic = ic;
-
- ic->ic_scan_curchan = scan_curchan;
- ic->ic_scan_mindwell = scan_mindwell;
-
- /*
- * TODO: all of the non-vap scan calls should be methods!
- */
-}
-
-void
+static void
ieee80211_swscan_detach(struct ieee80211com *ic)
{
struct ieee80211_scan_state *ss = ic->ic_scan;
@@ -155,11 +129,11 @@ ieee80211_swscan_detach(struct ieee80211com *ic)
ss->ss_ops = NULL;
}
ic->ic_scan = NULL;
- free(SCAN_PRIVATE(ss), M_80211_SCAN);
+ IEEE80211_FREE(SCAN_PRIVATE(ss), M_80211_SCAN);
}
}
-void
+static void
ieee80211_swscan_vattach(struct ieee80211vap *vap)
{
/* nothing to do for now */
@@ -169,7 +143,7 @@ ieee80211_swscan_vattach(struct ieee80211vap *vap)
}
-void
+static void
ieee80211_swscan_vdetach(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -185,7 +159,7 @@ ieee80211_swscan_vdetach(struct ieee80211vap *vap)
}
}
-void
+static void
ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, u_int duration)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -198,17 +172,6 @@ ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap, u_int duration)
SCAN_PRIVATE(ss)->ss_duration = duration;
}
-void
-ieee80211_swscan_run_scan_task(struct ieee80211vap *vap)
-{
- struct ieee80211com *ic = vap->iv_ic;
- struct ieee80211_scan_state *ss = ic->ic_scan;
-
- IEEE80211_LOCK_ASSERT(ic);
-
- ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task);
-}
-
/*
* Start a scan unless one is already going.
*/
@@ -272,7 +235,7 @@ ieee80211_swscan_start_scan_locked(const struct ieee80211_scanner *scan,
ic->ic_flags |= IEEE80211_F_SCAN;
/* Start scan task */
- ieee80211_swscan_run_scan_task(vap);
+ ieee80211_runtask(ic, &SCAN_PRIVATE(ss)->ss_scan_task);
}
return 1;
} else {
@@ -289,7 +252,7 @@ ieee80211_swscan_start_scan_locked(const struct ieee80211_scanner *scan,
*
* Called without the comlock held; grab the comlock as appropriate.
*/
-int
+static int
ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan,
struct ieee80211vap *vap, int flags,
u_int duration, u_int mindwell, u_int maxdwell,
@@ -316,7 +279,7 @@ ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan,
*
* XXX TODO: split out!
*/
-int
+static int
ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
struct ieee80211vap *vap, int flags,
u_int duration, u_int mindwell, u_int maxdwell,
@@ -374,7 +337,7 @@ ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
* Restart a previous scan. If the previous scan completed
* then we start again using the existing channel list.
*/
-int
+static int
ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan,
struct ieee80211vap *vap, int flags)
{
@@ -465,7 +428,7 @@ ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan,
/*
* Cancel any scan currently going on for the specified vap.
*/
-void
+static void
ieee80211_swscan_cancel_scan(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -499,7 +462,7 @@ ieee80211_swscan_cancel_scan(struct ieee80211vap *vap)
/*
* Cancel any scan currently going on.
*/
-void
+static void
ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -533,7 +496,7 @@ ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap)
* Public access to scan_next for drivers that manage
* scanning themselves (e.g. for firmware-based devices).
*/
-void
+static void
ieee80211_swscan_scan_next(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -551,7 +514,7 @@ ieee80211_swscan_scan_next(struct ieee80211vap *vap)
* Public access to scan_next for drivers that are not able to scan single
* channels (e.g. for firmware-based devices).
*/
-void
+static void
ieee80211_swscan_scan_done(struct ieee80211vap *vap)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -570,7 +533,7 @@ ieee80211_swscan_scan_done(struct ieee80211vap *vap)
* listen for beacons on the channel; if we receive something
* then we'll transmit a probe request.
*/
-void
+static void
ieee80211_swscan_probe_curchan(struct ieee80211vap *vap, int force)
{
struct ieee80211com *ic = vap->iv_ic;
@@ -898,7 +861,7 @@ done:
/*
* Process a beacon or probe response frame.
*/
-void
+static void
ieee80211_swscan_add_scan(struct ieee80211vap *vap,
struct ieee80211_channel *curchan,
const struct ieee80211_scanparams *sp,
@@ -946,3 +909,50 @@ ieee80211_swscan_add_scan(struct ieee80211vap *vap,
}
}
+static struct ieee80211_scan_methods swscan_methods = {
+ .sc_attach = ieee80211_swscan_attach,
+ .sc_detach = ieee80211_swscan_detach,
+ .sc_vattach = ieee80211_swscan_vattach,
+ .sc_vdetach = ieee80211_swscan_vdetach,
+ .sc_set_scan_duration = ieee80211_swscan_set_scan_duration,
+ .sc_start_scan = ieee80211_swscan_start_scan,
+ .sc_check_scan = ieee80211_swscan_check_scan,
+ .sc_bg_scan = ieee80211_swscan_bg_scan,
+ .sc_cancel_scan = ieee80211_swscan_cancel_scan,
+ .sc_cancel_anyscan = ieee80211_swscan_cancel_anyscan,
+ .sc_scan_next = ieee80211_swscan_scan_next,
+ .sc_scan_done = ieee80211_swscan_scan_done,
+ .sc_scan_probe_curchan = ieee80211_swscan_probe_curchan,
+ .sc_add_scan = ieee80211_swscan_add_scan
+};
+
+/*
+ * Default scan attach method.
+ */
+void
+ieee80211_swscan_attach(struct ieee80211com *ic)
+{
+ struct scan_state *ss;
+
+ /*
+ * Setup the default methods
+ */
+ ic->ic_scan_methods = &swscan_methods;
+
+ /* Allocate initial scan state */
+ ss = (struct scan_state *) IEEE80211_MALLOC(sizeof(struct scan_state),
+ M_80211_SCAN, IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
+ if (ss == NULL) {
+ ic->ic_scan = NULL;
+ return;
+ }
+ callout_init_mtx(&ss->ss_scan_timer, IEEE80211_LOCK_OBJ(ic), 0);
+ cv_init(&ss->ss_scan_cv, "scan");
+ TASK_INIT(&ss->ss_scan_task, 0, scan_task, ss);
+
+ ic->ic_scan = &ss->base;
+ ss->base.ss_ic = ic;
+
+ ic->ic_scan_curchan = scan_curchan;
+ ic->ic_scan_mindwell = scan_mindwell;
+}
diff --git a/sys/net80211/ieee80211_scan_sw.h b/sys/net80211/ieee80211_scan_sw.h
index 7bb0cc378642..8408933bfeb3 100644
--- a/sys/net80211/ieee80211_scan_sw.h
+++ b/sys/net80211/ieee80211_scan_sw.h
@@ -28,34 +28,5 @@
#define __NET80211_IEEE80211_SCAN_SW_H__
extern void ieee80211_swscan_attach(struct ieee80211com *ic);
-extern void ieee80211_swscan_detach(struct ieee80211com *ic);
-
-extern void ieee80211_swscan_vattach(struct ieee80211vap *vap);
-extern void ieee80211_swscan_vdetach(struct ieee80211vap *vap);
-
-extern int ieee80211_swscan_start_scan(const struct ieee80211_scanner *scan,
- struct ieee80211vap *vap, int flags,
- u_int duration, u_int mindwell, u_int maxdwell,
- u_int nssid, const struct ieee80211_scan_ssid ssids[]);
-extern void ieee80211_swscan_set_scan_duration(struct ieee80211vap *vap,
- u_int duration);
-extern void ieee80211_swscan_run_scan_task(struct ieee80211vap *vap);
-extern int ieee80211_swscan_check_scan(const struct ieee80211_scanner *scan,
- struct ieee80211vap *vap, int flags,
- u_int duration, u_int mindwell, u_int maxdwell,
- u_int nssid, const struct ieee80211_scan_ssid ssids[]);
-extern int ieee80211_swscan_bg_scan(const struct ieee80211_scanner *scan,
- struct ieee80211vap *vap, int flags);
-extern void ieee80211_swscan_cancel_scan(struct ieee80211vap *vap);
-extern void ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap);
-extern void ieee80211_swscan_scan_next(struct ieee80211vap *vap);
-extern void ieee80211_swscan_scan_done(struct ieee80211vap *vap);
-extern void ieee80211_swscan_probe_curchan(struct ieee80211vap *vap,
- int force);
-extern void ieee80211_swscan_add_scan(struct ieee80211vap *vap,
- struct ieee80211_channel *curchan,
- const struct ieee80211_scanparams *sp,
- const struct ieee80211_frame *wh,
- int subtype, int rssi, int noise);
#endif /* __NET80211_IEEE80211_SCAN_SW_H__ */
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index 267ad1149d73..81d75596b81b 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -70,9 +70,10 @@ __FBSDID("$FreeBSD$");
static void sta_vattach(struct ieee80211vap *);
static void sta_beacon_miss(struct ieee80211vap *);
static int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static int sta_input(struct ieee80211_node *, struct mbuf *, int, int);
+static int sta_input(struct ieee80211_node *, struct mbuf *,
+ const struct ieee80211_rx_stats *, int, int);
static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int rssi, int nf);
+ int subtype, const struct ieee80211_rx_stats *, int rssi, int nf);
static void sta_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
void
@@ -525,7 +526,8 @@ doprint(struct ieee80211vap *vap, int subtype)
* by the 802.11 layer.
*/
static int
-sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+sta_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -922,7 +924,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
wh = mtod(m, struct ieee80211_frame *);
wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
@@ -1058,7 +1060,7 @@ sta_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh,
switch (seq) {
case IEEE80211_AUTH_SHARED_PASS:
if (ni->ni_challenge != NULL) {
- free(ni->ni_challenge, M_80211_NODE);
+ IEEE80211_FREE(ni->ni_challenge, M_80211_NODE);
ni->ni_challenge = NULL;
}
if (status != 0) {
@@ -1285,13 +1287,15 @@ startbgscan(struct ieee80211vap *vap)
}
static void
-sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
+ const struct ieee80211_rx_stats *rxs,
+ int rssi, int nf)
{
#define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
#define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP)
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_channel *rxchan = ic->ic_curchan;
struct ieee80211_frame *wh;
uint8_t *frm, *efrm;
uint8_t *rates, *xrates, *wme, *htcap, *htinfo;
@@ -1305,6 +1309,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
case IEEE80211_FC0_SUBTYPE_BEACON: {
struct ieee80211_scanparams scan;
+ struct ieee80211_channel *c;
/*
* We process beacon/probe response frames:
* o when scanning, or
@@ -1316,8 +1321,16 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
vap->iv_stats.is_rx_mgtdiscard++;
return;
}
+
+ /* Override RX channel as appropriate */
+ if (rxs != NULL) {
+ c = ieee80211_lookup_channel_rxstatus(vap, rxs);
+ if (c != NULL)
+ rxchan = c;
+ }
+
/* XXX probe response in sta mode when !scanning? */
- if (ieee80211_parse_beacon(ni, m0, &scan) != 0) {
+ if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0) {
if (! (ic->ic_flags & IEEE80211_F_SCAN))
vap->iv_stats.is_beacon_bad++;
return;
@@ -1484,7 +1497,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
* our ap.
*/
if (ic->ic_flags & IEEE80211_F_SCAN) {
- ieee80211_add_scan(vap, ic->ic_curchan,
+ ieee80211_add_scan(vap, rxchan,
&scan, wh, subtype, rssi, nf);
} else if (contbgscan(vap)) {
ieee80211_bg_scan(vap, 0);
@@ -1529,7 +1542,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
ieee80211_probe_curchan(vap, 1);
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
}
- ieee80211_add_scan(vap, ic->ic_curchan, &scan, wh,
+ ieee80211_add_scan(vap, rxchan, &scan, wh,
subtype, rssi, nf);
return;
}
diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c
index 81a4b43075f3..2e2bbd18be84 100644
--- a/sys/net80211/ieee80211_superg.c
+++ b/sys/net80211/ieee80211_superg.c
@@ -100,9 +100,9 @@ ieee80211_superg_attach(struct ieee80211com *ic)
struct ieee80211_superg *sg;
if (ic->ic_caps & IEEE80211_C_FF) {
- sg = (struct ieee80211_superg *) malloc(
+ sg = (struct ieee80211_superg *) IEEE80211_MALLOC(
sizeof(struct ieee80211_superg), M_80211_VAP,
- M_NOWAIT | M_ZERO);
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (sg == NULL) {
printf("%s: cannot allocate SuperG state block\n",
__func__);
@@ -117,7 +117,7 @@ void
ieee80211_superg_detach(struct ieee80211com *ic)
{
if (ic->ic_superg != NULL) {
- free(ic->ic_superg, M_80211_VAP);
+ IEEE80211_FREE(ic->ic_superg, M_80211_VAP);
ic->ic_superg = NULL;
}
}
diff --git a/sys/net80211/ieee80211_tdma.c b/sys/net80211/ieee80211_tdma.c
index 08acc3897c51..278decf97b9a 100644
--- a/sys/net80211/ieee80211_tdma.c
+++ b/sys/net80211/ieee80211_tdma.c
@@ -115,7 +115,7 @@ static void tdma_vdetach(struct ieee80211vap *vap);
static int tdma_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void tdma_beacon_miss(struct ieee80211vap *vap);
static void tdma_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int rssi, int nf);
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf);
static int tdma_update(struct ieee80211vap *vap,
const struct ieee80211_tdma_param *tdma, struct ieee80211_node *ni,
int pickslot);
@@ -149,8 +149,9 @@ ieee80211_tdma_vattach(struct ieee80211vap *vap)
KASSERT(vap->iv_caps & IEEE80211_C_TDMA,
("not a tdma vap, caps 0x%x", vap->iv_caps));
- ts = (struct ieee80211_tdma_state *) malloc(
- sizeof(struct ieee80211_tdma_state), M_80211_VAP, M_NOWAIT | M_ZERO);
+ ts = (struct ieee80211_tdma_state *) IEEE80211_MALLOC(
+ sizeof(struct ieee80211_tdma_state), M_80211_VAP,
+ IEEE80211_M_NOWAIT | IEEE80211_M_ZERO);
if (ts == NULL) {
printf("%s: cannot allocate TDMA state block\n", __func__);
/* NB: fall back to adhdemo mode */
@@ -199,7 +200,7 @@ tdma_vdetach(struct ieee80211vap *vap)
return;
}
ts->tdma_opdetach(vap);
- free(vap->iv_tdma, M_80211_VAP);
+ IEEE80211_FREE(vap->iv_tdma, M_80211_VAP);
vap->iv_tdma = NULL;
setackpolicy(vap->iv_ic, 0); /* enable ACK's */
@@ -320,7 +321,7 @@ tdma_beacon_miss(struct ieee80211vap *vap)
static void
tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+ int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211com *ic = ni->ni_ic;
struct ieee80211vap *vap = ni->ni_vap;
@@ -331,7 +332,8 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
struct ieee80211_scanparams scan;
- if (ieee80211_parse_beacon(ni, m0, &scan) != 0)
+ /* XXX TODO: use rxstatus to determine off-channel beacons */
+ if (ieee80211_parse_beacon(ni, m0, ic->ic_curchan, &scan) != 0)
return;
if (scan.tdma == NULL) {
/*
@@ -391,7 +393,7 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
* 2x parsing of the frame but should happen infrequently
*/
}
- ts->tdma_recv_mgmt(ni, m0, subtype, rssi, nf);
+ ts->tdma_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
}
/*
diff --git a/sys/net80211/ieee80211_tdma.h b/sys/net80211/ieee80211_tdma.h
index 2fe591f73e3e..76b9ed1c3b00 100644
--- a/sys/net80211/ieee80211_tdma.h
+++ b/sys/net80211/ieee80211_tdma.h
@@ -81,7 +81,8 @@ struct ieee80211_tdma_state {
int (*tdma_newstate)(struct ieee80211vap *, enum ieee80211_state,
int arg);
void (*tdma_recv_mgmt)(struct ieee80211_node *,
- struct mbuf *, int, int, int);
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *rxs, int, int);
void (*tdma_opdetach)(struct ieee80211vap *);
};
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 471069702324..26238b88e4f1 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -117,6 +117,8 @@ struct ieee80211_frame;
struct ieee80211com {
struct ifnet *ic_ifp; /* associated device */
+ void *ic_softc; /* driver softc */
+ const char *ic_name; /* usually device name */
ieee80211_com_lock_t ic_comlock; /* state update lock */
ieee80211_tx_lock_t ic_txlock; /* ic/vap TX lock */
TAILQ_HEAD(, ieee80211vap) ic_vaps; /* list of vap instances */
@@ -133,6 +135,9 @@ struct ieee80211com {
struct task ic_bmiss_task; /* deferred beacon miss hndlr */
struct task ic_chw_task; /* deferred HT CHW update */
+ counter_u64_t ic_ierrors; /* input errors */
+ counter_u64_t ic_oerrors; /* output errors */
+
uint32_t ic_flags; /* state flags */
uint32_t ic_flags_ext; /* extended state flags */
uint32_t ic_flags_ht; /* HT state flags */
@@ -192,6 +197,7 @@ struct ieee80211com {
struct ieee80211_dfs_state ic_dfs; /* DFS state */
struct ieee80211_scan_state *ic_scan; /* scan state */
+ struct ieee80211_scan_methods *ic_scan_methods; /* scan methods */
int ic_lastdata; /* time of last data frame */
int ic_lastscan; /* time last scan completed */
@@ -256,11 +262,11 @@ struct ieee80211com {
struct mbuf *,
const struct ieee80211_bpf_params *);
/* update device state for 802.11 slot time change */
- void (*ic_updateslot)(struct ifnet *);
+ void (*ic_updateslot)(struct ieee80211com *);
/* handle multicast state changes */
- void (*ic_update_mcast)(struct ifnet *);
+ void (*ic_update_mcast)(struct ieee80211com *);
/* handle promiscuous mode changes */
- void (*ic_update_promisc)(struct ifnet *);
+ void (*ic_update_promisc)(struct ieee80211com *);
/* new station association callback/notification */
void (*ic_newassoc)(struct ieee80211_node *, int);
/* TDMA update notification */
@@ -466,9 +472,13 @@ struct ieee80211vap {
void (*iv_opdetach)(struct ieee80211vap *);
/* receive processing */
int (*iv_input)(struct ieee80211_node *,
- struct mbuf *, int, int);
+ struct mbuf *,
+ const struct ieee80211_rx_stats *,
+ int, int);
void (*iv_recv_mgmt)(struct ieee80211_node *,
- struct mbuf *, int, int, int);
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *,
+ int, int);
void (*iv_recv_ctl)(struct ieee80211_node *,
struct mbuf *, int);
void (*iv_deliver_data)(struct ieee80211vap *,
@@ -496,13 +506,8 @@ struct ieee80211vap {
int (*iv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
/* 802.3 output method for raw frame xmit */
-#if __FreeBSD_version >= 1000031
int (*iv_output)(struct ifnet *, struct mbuf *,
const struct sockaddr *, struct route *);
-#else
- int (*iv_output)(struct ifnet *, struct mbuf *,
- struct sockaddr *, struct route *);
-#endif
uint64_t iv_spare[6];
};
MALLOC_DECLARE(M_80211_VAP);
@@ -675,6 +680,7 @@ MALLOC_DECLARE(M_80211_VAP);
"\20\1LDPC\2CHWIDTH40\5GREENFIELD\6SHORTGI20\7SHORTGI40\10TXSTBC" \
"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
+int ic_printf(struct ieee80211com *, const char *, ...) __printflike(2, 3);
void ieee80211_ifattach(struct ieee80211com *,
const uint8_t macaddr[IEEE80211_ADDR_LEN]);
void ieee80211_ifdetach(struct ieee80211com *);
@@ -707,6 +713,8 @@ struct ieee80211_channel *ieee80211_find_channel(struct ieee80211com *,
int freq, int flags);
struct ieee80211_channel *ieee80211_find_channel_byieee(struct ieee80211com *,
int ieee, int flags);
+struct ieee80211_channel *ieee80211_lookup_channel_rxstatus(struct ieee80211vap *,
+ const struct ieee80211_rx_stats *);
int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode);
enum ieee80211_phymode ieee80211_chan2mode(const struct ieee80211_channel *);
uint32_t ieee80211_mac_hash(const struct ieee80211com *,
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index fc7725948b84..1d3f30a7a48e 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -64,9 +64,10 @@ __FBSDID("$FreeBSD$");
static void wds_vattach(struct ieee80211vap *);
static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int);
-static int wds_input(struct ieee80211_node *ni, struct mbuf *m, int, int);
-static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *,
- int subtype, int, int);
+static int wds_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int, int);
+static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *, int subtype,
+ const struct ieee80211_rx_stats *, int, int);
void
ieee80211_wds_attach(struct ieee80211com *ic)
@@ -408,7 +409,8 @@ wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
* by the 802.11 layer.
*/
static int
-wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
+wds_input(struct ieee80211_node *ni, struct mbuf *m,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
@@ -718,7 +720,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
goto out;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
+ vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
@@ -744,8 +746,8 @@ out:
}
static void
-wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
- int subtype, int rssi, int nf)
+wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
+ const struct ieee80211_rx_stats *rxs, int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index 456990019c2f..21add4329ccd 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -555,7 +555,9 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
(stcb->asoc.primary_destination->dest_state &
SCTP_ADDR_UNCONFIRMED) == 0) {
- sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER + SCTP_LOC_7);
+ sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
+ stcb->sctp_ep, stcb, NULL,
+ SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1);
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
SCTP_MOBILITY_FASTHANDOFF)) {
sctp_assoc_immediate_retrans(stcb,
@@ -991,7 +993,7 @@ sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.primary_destination->ro._l_addr.sa);
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb,
stcb->asoc.deleted_primary,
- SCTP_FROM_SCTP_TIMER + SCTP_LOC_8);
+ SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
stcb->asoc.num_send_timers_up--;
if (stcb->asoc.num_send_timers_up < 0) {
stcb->asoc.num_send_timers_up = 0;
@@ -1030,7 +1032,7 @@ sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
SCTPDBG(SCTP_DEBUG_ASCONF1, "net_immediate_retrans: RTO is %d\n", net->RTO);
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net,
- SCTP_FROM_SCTP_TIMER + SCTP_LOC_5);
+ SCTP_FROM_SCTP_ASCONF + SCTP_LOC_4);
stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
net->error_count = 0;
TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
@@ -1684,7 +1686,7 @@ sctp_handle_asconf_ack(struct mbuf *m, int offset,
if (serial_num == asoc->asconf_seq_out - 1) {
/* stop our timer */
sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
- SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
+ SCTP_FROM_SCTP_ASCONF + SCTP_LOC_5);
}
/* process the ASCONF-ACK contents */
ack_length = ntohs(cp->ch.chunk_length) -
@@ -1975,7 +1977,8 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* sent when the state goes open.
*/
if (status == 0 &&
- SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
+ ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
+ (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
#ifdef SCTP_TIMER_BASED_ASCONF
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
stcb, stcb->asoc.primary_destination);
@@ -2223,7 +2226,8 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* count of queued params. If in the non-open
* state, these get sent when the assoc goes open.
*/
- if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
+ if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
+ (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
if (status >= 0) {
num_queued++;
}
@@ -2283,7 +2287,8 @@ sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
"set_primary_ip_address_sa: queued on tcb=%p, ",
(void *)stcb);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
- if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
+ if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
+ (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
#ifdef SCTP_TIMER_BASED_ASCONF
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
stcb->sctp_ep, stcb,
@@ -2319,7 +2324,8 @@ sctp_set_primary_ip_address(struct sctp_ifa *ifa)
SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address: queued on stcb=%p, ",
(void *)stcb);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
- if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
+ if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
+ (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
#ifdef SCTP_TIMER_BASED_ASCONF
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
stcb->sctp_ep, stcb,
diff --git a/sys/netinet/sctp_cc_functions.c b/sys/netinet/sctp_cc_functions.c
index 17a897b93d45..d616d1949496 100644
--- a/sys/netinet/sctp_cc_functions.c
+++ b/sys/netinet/sctp_cc_functions.c
@@ -226,7 +226,8 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
}
sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
- stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_CC_FUNCTIONS + SCTP_LOC_1);
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net);
}
@@ -1732,7 +1733,8 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
}
sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
- stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_CC_FUNCTIONS + SCTP_LOC_2);
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net);
}
@@ -2264,7 +2266,8 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb,
}
sctp_timer_stop(SCTP_TIMER_TYPE_SEND,
- stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_CC_FUNCTIONS + SCTP_LOC_3);
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
stcb->sctp_ep, stcb, net);
}
diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h
index de451651a6a6..d90bd2502ad4 100644
--- a/sys/netinet/sctp_constants.h
+++ b/sys/netinet/sctp_constants.h
@@ -765,18 +765,19 @@ __FBSDID("$FreeBSD$");
*/
/* File defines */
-#define SCTP_FROM_SCTP_INPUT 0x10000000
-#define SCTP_FROM_SCTP_PCB 0x20000000
-#define SCTP_FROM_SCTP_INDATA 0x30000000
-#define SCTP_FROM_SCTP_TIMER 0x40000000
-#define SCTP_FROM_SCTP_USRREQ 0x50000000
-#define SCTP_FROM_SCTPUTIL 0x60000000
-#define SCTP_FROM_SCTP6_USRREQ 0x70000000
-#define SCTP_FROM_SCTP_ASCONF 0x80000000
-#define SCTP_FROM_SCTP_OUTPUT 0x90000000
-#define SCTP_FROM_SCTP_PEELOFF 0xa0000000
-#define SCTP_FROM_SCTP_PANDA 0xb0000000
-#define SCTP_FROM_SCTP_SYSCTL 0xc0000000
+#define SCTP_FROM_SCTP_INPUT 0x10000000
+#define SCTP_FROM_SCTP_PCB 0x20000000
+#define SCTP_FROM_SCTP_INDATA 0x30000000
+#define SCTP_FROM_SCTP_TIMER 0x40000000
+#define SCTP_FROM_SCTP_USRREQ 0x50000000
+#define SCTP_FROM_SCTPUTIL 0x60000000
+#define SCTP_FROM_SCTP6_USRREQ 0x70000000
+#define SCTP_FROM_SCTP_ASCONF 0x80000000
+#define SCTP_FROM_SCTP_OUTPUT 0x90000000
+#define SCTP_FROM_SCTP_PEELOFF 0xa0000000
+#define SCTP_FROM_SCTP_PANDA 0xb0000000
+#define SCTP_FROM_SCTP_SYSCTL 0xc0000000
+#define SCTP_FROM_SCTP_CC_FUNCTIONS 0xd0000000
/* Location ID's */
#define SCTP_LOC_1 0x00000001
@@ -812,6 +813,8 @@ __FBSDID("$FreeBSD$");
#define SCTP_LOC_31 0x0000001f
#define SCTP_LOC_32 0x00000020
#define SCTP_LOC_33 0x00000021
+#define SCTP_LOC_34 0x00000022
+#define SCTP_LOC_35 0x00000023
/* Free assoc codes */
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index d3b485560305..50a662864a02 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -1034,7 +1034,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.TSN_seq,
(chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_7;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_8;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
@@ -1056,7 +1056,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.stream_number,
chk->rec.data.stream_seq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_8;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_9;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
@@ -1073,7 +1073,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.stream_number,
chk->rec.data.stream_seq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_9;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_10;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
@@ -1100,7 +1100,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.stream_number,
chk->rec.data.stream_seq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_10;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_11;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
@@ -1123,7 +1123,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.stream_number,
chk->rec.data.stream_seq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_11;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_12;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
@@ -1144,7 +1144,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.stream_number,
chk->rec.data.stream_seq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_12;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_13;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
@@ -1162,7 +1162,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.TSN_seq,
(chk->rec.data.rcv_flags & SCTP_DATA_UNORDERED) ? 1 : 0);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_12;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_14;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
@@ -1184,7 +1184,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
chk->rec.data.stream_number,
chk->rec.data.stream_seq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_13;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_15;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return;
@@ -1476,7 +1476,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->strmin[strmno].last_sequence_delivered,
tsn, strmno, strmseq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_14;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
return (0);
@@ -1713,7 +1713,7 @@ failed_pdapi_express_del:
snprintf(msg, sizeof(msg), "Reas. queue emtpy, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
tsn, strmno, strmseq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_15;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_17;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
if (last_chunk) {
@@ -1732,7 +1732,7 @@ failed_pdapi_express_del:
snprintf(msg, sizeof(msg), "PD ongoing, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
tsn, strmno, strmseq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_18;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
if (last_chunk) {
@@ -1761,7 +1761,7 @@ failed_pdapi_express_del:
snprintf(msg, sizeof(msg), "No PD ongoing, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
tsn, strmno, strmseq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_17;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
*abort_flag = 1;
if (last_chunk) {
@@ -2159,7 +2159,8 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap)
*/
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
+ stcb->sctp_ep, stcb, NULL,
+ SCTP_FROM_SCTP_INDATA + SCTP_LOC_20);
}
sctp_send_shutdown(stcb,
((stcb->asoc.alternate) ? stcb->asoc.alternate : stcb->asoc.primary_destination));
@@ -2382,7 +2383,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
snprintf(msg, sizeof(msg), "DATA chunk of length %d",
chk_length);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_21;
sctp_abort_association(inp, stcb, m, iphlen,
src, dst, sh, op_err,
mflowtype, mflowid,
@@ -2397,7 +2398,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
struct mbuf *op_err;
op_err = sctp_generate_no_user_data_cause(ch->dp.tsn);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_22;
sctp_abort_association(inp, stcb, m, iphlen,
src, dst, sh, op_err,
mflowtype, mflowid,
@@ -3462,12 +3463,18 @@ sctp_fs_audit(struct sctp_association *asoc)
{
struct sctp_tmit_chunk *chk;
int inflight = 0, resend = 0, inbetween = 0, acked = 0, above = 0;
- int entry_flight, entry_cnt, ret;
+ int ret;
+
+#ifndef INVARIANTS
+ int entry_flight, entry_cnt;
+
+#endif
+ ret = 0;
+#ifndef INVARIANTS
entry_flight = asoc->total_flight;
entry_cnt = asoc->total_flight_count;
- ret = 0;
-
+#endif
if (asoc->pr_sctp_cnt >= asoc->sent_queue_cnt)
return (0);
@@ -3622,7 +3629,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal than TSN %8.8x",
cumack, send_s);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_23;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
return;
}
@@ -3818,7 +3825,9 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
}
if (net->dest_state & SCTP_ADDR_PF) {
net->dest_state &= ~SCTP_ADDR_PF;
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_INDATA + SCTP_LOC_24);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
asoc->cc_functions.sctp_cwnd_update_exit_pf(stcb, net);
/* Done with this net */
@@ -3904,7 +3913,7 @@ again:
} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
- SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
+ SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
}
}
}
@@ -3978,7 +3987,7 @@ again:
*abort_now = 1;
/* XXX */
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_26;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
} else {
struct sctp_nets *netp;
@@ -4191,7 +4200,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal than TSN %8.8x",
cum_ack, send_s);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_27;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
return;
}
@@ -4223,7 +4232,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
/* stop any timers */
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
- stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
+ stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_28);
net->partial_bytes_acked = 0;
net->flight_size = 0;
}
@@ -4428,14 +4437,14 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
if (net->new_pseudo_cumack)
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
- SCTP_FROM_SCTP_INDATA + SCTP_LOC_27);
+ SCTP_FROM_SCTP_INDATA + SCTP_LOC_29);
}
} else {
if (accum_moved) {
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
- stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_28);
+ stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_30);
}
}
}
@@ -4608,7 +4617,9 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
}
if (net->dest_state & SCTP_ADDR_PF) {
net->dest_state &= ~SCTP_ADDR_PF;
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_INDATA + SCTP_LOC_31);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
asoc->cc_functions.sctp_cwnd_update_exit_pf(stcb, net);
/* Done with this net */
@@ -4631,7 +4642,8 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
/* stop all timers */
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
- stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_30);
+ stcb, net,
+ SCTP_FROM_SCTP_INDATA + SCTP_LOC_32);
net->flight_size = 0;
net->partial_bytes_acked = 0;
}
@@ -4687,7 +4699,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
*abort_now = 1;
/* XXX */
op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_31;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_33;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
return;
} else {
@@ -4839,7 +4851,7 @@ again:
} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
- SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
+ SCTP_FROM_SCTP_INDATA + SCTP_LOC_34);
}
}
}
@@ -5129,7 +5141,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
"New cum ack %8.8x too high, highest TSN %8.8x",
new_cum_tsn, asoc->highest_tsn_inside_map);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
- stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_33;
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_35;
sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
return;
}
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 048dfd3d094c..89047cbd60c1 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -513,7 +513,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
* primary.
*/
sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep, stcb,
- asoc->primary_destination, SCTP_FROM_SCTP_INPUT + SCTP_LOC_4);
+ asoc->primary_destination, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
/* calculate the RTO */
net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, sctp_align_safe_nocopy,
@@ -633,7 +633,8 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
}
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
stcb, 0, (void *)r_net, SCTP_SO_NOT_LOCKED);
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb,
+ r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_4);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
}
old_error_counter = r_net->error_count;
@@ -654,7 +655,8 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
stcb->asoc.cc_functions.sctp_cwnd_update_exit_pf(stcb, net);
}
if (old_error_counter > 0) {
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
+ stcb, r_net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_5);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, r_net);
}
if (r_net == stcb->asoc.primary_destination) {
@@ -673,7 +675,9 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
sctp_is_mobility_feature_on(stcb->sctp_ep,
SCTP_MOBILITY_PRIM_DELETED)) {
- sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER + SCTP_LOC_7);
+ sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
+ stcb->sctp_ep, stcb, NULL,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_6);
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
SCTP_MOBILITY_FASTHANDOFF)) {
sctp_assoc_immediate_retrans(stcb,
@@ -795,7 +799,8 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
error = 0;
}
/* stop any receive timers */
- sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_6);
+ sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_7);
/* notify user of the abort and clean up... */
sctp_abort_notification(stcb, 1, error, abort, SCTP_SO_NOT_LOCKED);
/* free the tcb */
@@ -817,7 +822,7 @@ sctp_handle_abort(struct sctp_abort_chunk *abort,
#endif
stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
- SCTP_FROM_SCTP_INPUT + SCTP_LOC_6);
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -932,7 +937,8 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
* stop the shutdown timer, since we WILL move to
* SHUTDOWN-ACK-SENT.
*/
- sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
+ sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
+ net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_9);
}
/* Now is there unsent data on a stream somewhere? */
some_on_streamwheel = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
@@ -1025,7 +1031,8 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
}
#endif
/* stop the timer */
- sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_9);
+ sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_10);
/* send SHUTDOWN-COMPLETE */
sctp_send_shutdown_complete(stcb, net, 0);
/* notify upper layer protocol */
@@ -1046,7 +1053,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
- SCTP_FROM_SCTP_INPUT + SCTP_LOC_10);
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_11);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -1206,7 +1213,7 @@ sctp_handle_error(struct sctp_chunkhdr *ch,
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
(void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
- SCTP_FROM_SCTP_INPUT + SCTP_LOC_11);
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_12);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -1558,9 +1565,12 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
return (NULL);
}
/* we have already processed the INIT so no problem */
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb,
- net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_12);
- sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_13);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp,
+ stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_13);
+ sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp,
+ stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_14);
/* update current state */
if (SCTP_GET_STATE(asoc) == SCTP_STATE_COOKIE_ECHOED)
SCTP_STAT_INCR_COUNTER32(sctps_activeestab);
@@ -1720,7 +1730,8 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
}
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 8;
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_14);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_15);
sctp_stop_all_cookie_timers(stcb);
/*
* since we did not send a HB make sure we don't double
@@ -1865,8 +1876,10 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* temp code */
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 12;
- sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_15);
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_16);
+ sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_16);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_17);
/* notify upper layer */
*notification = SCTP_NOTIFY_ASSOC_RESTART;
@@ -2134,7 +2147,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
SCTP_TCB_LOCK(stcb);
#endif
(void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
- SCTP_FROM_SCTP_INPUT + SCTP_LOC_16);
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_18);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -2165,7 +2178,8 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
SCTP_SOCKET_LOCK(so, 1);
SCTP_TCB_LOCK(stcb);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_16);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_19);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -2182,7 +2196,8 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
SCTP_SOCKET_LOCK(so, 1);
SCTP_TCB_LOCK(stcb);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_17);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_20);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -2211,7 +2226,8 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
SCTP_SOCKET_LOCK(so, 1);
SCTP_TCB_LOCK(stcb);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_18);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_21);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -2271,7 +2287,8 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
SCTP_SOCKET_LOCK(so, 1);
SCTP_TCB_LOCK(stcb);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_19);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_22);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -2741,7 +2758,8 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
SCTP_TCB_LOCK((*stcb));
atomic_subtract_int(&(*stcb)->asoc.refcnt, 1);
#endif
- (void)sctp_free_assoc(*inp_p, *stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_20);
+ (void)sctp_free_assoc(*inp_p, *stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_23);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(pcb_so, 1);
#endif
@@ -3173,7 +3191,8 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
}
#endif
/* stop the timer */
- sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_22);
+ sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_24);
SCTP_STAT_INCR_COUNTER32(sctps_shutdown);
/* free the TCB */
SCTPDBG(SCTP_DEBUG_INPUT2,
@@ -3186,7 +3205,8 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_23);
+ (void)sctp_free_assoc(stcb->sctp_ep, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_25);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -3294,7 +3314,8 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
/* restart the timer */
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
- stcb, tp1->whoTo, SCTP_FROM_SCTP_INPUT + SCTP_LOC_24);
+ stcb, tp1->whoTo,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_26);
sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, tp1->whoTo);
@@ -3362,7 +3383,8 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
* this, otherwise we let the timer fire.
*/
sctp_timer_stop(SCTP_TIMER_TYPE_INIT, stcb->sctp_ep,
- stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_25);
+ stcb, net,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_27);
sctp_send_initiate(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED);
}
break;
@@ -3539,7 +3561,8 @@ sctp_clean_up_stream_reset(struct sctp_tcb *stcb)
}
asoc = &stcb->asoc;
- sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb, chk->whoTo, SCTP_FROM_SCTP_INPUT + SCTP_LOC_26);
+ sctp_timer_stop(SCTP_TIMER_TYPE_STRRESET, stcb->sctp_ep, stcb,
+ chk->whoTo, SCTP_FROM_SCTP_INPUT + SCTP_LOC_28);
TAILQ_REMOVE(&asoc->control_send_queue,
chk,
sctp_next);
@@ -4783,7 +4806,8 @@ process_control_chunks:
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_27);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_29);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -5203,7 +5227,8 @@ process_control_chunks:
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_27);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_30);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -5381,7 +5406,8 @@ process_control_chunks:
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_INPUT + SCTP_LOC_29);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_INPUT + SCTP_LOC_31);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index ed3b9ec6818d..a52ed4e677d2 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -3160,8 +3160,6 @@ again_with_private_addresses_allowed:
sifa = NULL;
continue;
}
- } else {
- SCTP_PRINTF("Stcb is null - no print\n");
}
atomic_add_int(&sifa->refcount, 1);
goto out;
@@ -4063,7 +4061,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sctp_route_t iproute;
int len;
- len = sizeof(struct ip) + sizeof(struct sctphdr);
+ len = SCTP_MIN_V4_OVERHEAD;
if (port) {
len += sizeof(struct udphdr);
}
@@ -4345,7 +4343,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
flowlabel = ntohl(((struct in6pcb *)inp)->in6p_flowinfo);
}
flowlabel &= 0x000fffff;
- len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
+ len = SCTP_MIN_OVERHEAD;
if (port) {
len += sizeof(struct udphdr);
}
@@ -5107,10 +5105,11 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
if (op_err == NULL) {
/* Ok need to try to get a mbuf */
#ifdef INET6
- l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+ l_len = SCTP_MIN_OVERHEAD;
#else
- l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+ l_len = SCTP_MIN_V4_OVERHEAD;
#endif
+ l_len += sizeof(struct sctp_chunkhdr);
l_len += plen;
l_len += sizeof(struct sctp_paramhdr);
op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA);
@@ -5176,10 +5175,11 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
/* Ok need to try to get an mbuf */
#ifdef INET6
- l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+ l_len = SCTP_MIN_OVERHEAD;
#else
- l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+ l_len = SCTP_MIN_V4_OVERHEAD;
#endif
+ l_len += sizeof(struct sctp_chunkhdr);
l_len += plen;
l_len += sizeof(struct sctp_paramhdr);
op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA);
@@ -5251,10 +5251,11 @@ invalid_size:
int l_len;
#ifdef INET6
- l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+ l_len = SCTP_MIN_OVERHEAD;
#else
- l_len = sizeof(struct ip) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
+ l_len = SCTP_MIN_V4_OVERHEAD;
#endif
+ l_len += sizeof(struct sctp_chunkhdr);
l_len += (2 * sizeof(struct sctp_paramhdr));
op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA);
if (op_err) {
@@ -5588,11 +5589,7 @@ do_a_abort:
stc.ipv6_addr_legal = 0;
stc.ipv4_addr_legal = 1;
}
-#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
- stc.ipv4_scope = 1;
-#else
stc.ipv4_scope = 0;
-#endif
if (net == NULL) {
to = src;
switch (dst->sa_family) {
@@ -5613,13 +5610,10 @@ do_a_abort:
stc.laddr_type = SCTP_IPV4_ADDRESS;
/* scope_id is only for v6 */
stc.scope_id = 0;
-#ifndef SCTP_DONT_DO_PRIVADDR_SCOPE
- if (IN4_ISPRIVATE_ADDRESS(&src4->sin_addr)) {
+ if ((IN4_ISPRIVATE_ADDRESS(&src4->sin_addr)) ||
+ (IN4_ISPRIVATE_ADDRESS(&dst4->sin_addr))) {
stc.ipv4_scope = 1;
}
-#else
- stc.ipv4_scope = 1;
-#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
/* Must use the address in this case */
if (sctp_is_address_on_local_host(src, vrf_id)) {
stc.loopback_scope = 1;
@@ -5641,16 +5635,18 @@ do_a_abort:
stc.local_scope = 0;
stc.site_scope = 1;
stc.ipv4_scope = 1;
- } else if (IN6_IS_ADDR_LINKLOCAL(&src6->sin6_addr)) {
+ } else if (IN6_IS_ADDR_LINKLOCAL(&src6->sin6_addr) ||
+ IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr)) {
/*
- * If the new destination is a
- * LINK_LOCAL we must have common
- * both site and local scope. Don't
- * set local scope though since we
- * must depend on the source to be
- * added implicitly. We cannot
- * assure just because we share one
- * link that all links are common.
+ * If the new destination or source
+ * is a LINK_LOCAL we must have
+ * common both site and local scope.
+ * Don't set local scope though
+ * since we must depend on the
+ * source to be added implicitly. We
+ * cannot assure just because we
+ * share one link that all links are
+ * common.
*/
stc.local_scope = 0;
stc.site_scope = 1;
@@ -5666,11 +5662,12 @@ do_a_abort:
* pull out the scope_id from
* incoming pkt
*/
- } else if (IN6_IS_ADDR_SITELOCAL(&src6->sin6_addr)) {
+ } else if (IN6_IS_ADDR_SITELOCAL(&src6->sin6_addr) ||
+ IN6_IS_ADDR_SITELOCAL(&dst6->sin6_addr)) {
/*
- * If the new destination is
- * SITE_LOCAL then we must have site
- * scope in common.
+ * If the new destination or source
+ * is SITE_LOCAL then we must have
+ * site scope in common.
*/
stc.site_scope = 1;
}
@@ -7961,12 +7958,12 @@ again_one_more_time:
switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
#ifdef INET
case AF_INET:
- mtu = net->mtu - (sizeof(struct ip) + sizeof(struct sctphdr));
+ mtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
break;
#endif
#ifdef INET6
case AF_INET6:
- mtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
+ mtu = net->mtu - SCTP_MIN_OVERHEAD;
break;
#endif
default:
@@ -7988,6 +7985,7 @@ again_one_more_time:
} else {
r_mtu = mtu;
}
+ error = 0;
/************************/
/* ASCONF transmission */
/************************/
@@ -8111,6 +8109,12 @@ again_one_more_time:
* it is used to do appropriate
* source address selection.
*/
+ if (*now_filled == 0) {
+ (void)SCTP_GETTIME_TIMEVAL(now);
+ *now_filled = 1;
+ }
+ net->last_sent_time = *now;
+ hbflag = 0;
if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
outchain, auth_offset, auth,
@@ -8121,21 +8125,18 @@ again_one_more_time:
net->port, NULL,
0, 0,
so_locked))) {
- if (error == ENOBUFS) {
- asoc->ifp_had_enobuf = 1;
- SCTP_STAT_INCR(sctps_lowlevelerr);
- }
+ /*
+ * error, we could not
+ * output
+ */
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
}
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
+ if (error == ENOBUFS) {
+ asoc->ifp_had_enobuf = 1;
+ SCTP_STAT_INCR(sctps_lowlevelerr);
}
- hbflag = 0;
/* error, could not output */
if (error == EHOSTUNREACH) {
/*
@@ -8146,17 +8147,10 @@ again_one_more_time:
sctp_move_chunks_from_net(stcb, net);
}
*reason_code = 7;
- continue;
- } else
- asoc->ifp_had_enobuf = 0;
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
+ break;
} else {
- net->last_sent_time = *now;
+ asoc->ifp_had_enobuf = 0;
}
- hbflag = 0;
/*
* increase the number we sent, if a
* cookie is sent we don't tell them
@@ -8189,6 +8183,10 @@ again_one_more_time:
}
}
}
+ if (error != 0) {
+ /* try next net */
+ continue;
+ }
/************************/
/* Control transmission */
/************************/
@@ -8327,7 +8325,8 @@ again_one_more_time:
/* turn off the timer */
if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
- inp, stcb, net, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_1);
+ inp, stcb, net,
+ SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_1);
}
}
ctl_cnt++;
@@ -8384,6 +8383,15 @@ again_one_more_time:
sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net);
cookie = 0;
}
+ /* Only HB or ASCONF advances time */
+ if (hbflag) {
+ if (*now_filled == 0) {
+ (void)SCTP_GETTIME_TIMEVAL(now);
+ *now_filled = 1;
+ }
+ net->last_sent_time = *now;
+ hbflag = 0;
+ }
if ((error = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
outchain,
@@ -8395,23 +8403,17 @@ again_one_more_time:
net->port, NULL,
0, 0,
so_locked))) {
- if (error == ENOBUFS) {
- asoc->ifp_had_enobuf = 1;
- SCTP_STAT_INCR(sctps_lowlevelerr);
- }
+ /*
+ * error, we could not
+ * output
+ */
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
}
- /* error, could not output */
- if (hbflag) {
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
- }
- hbflag = 0;
+ if (error == ENOBUFS) {
+ asoc->ifp_had_enobuf = 1;
+ SCTP_STAT_INCR(sctps_lowlevelerr);
}
if (error == EHOSTUNREACH) {
/*
@@ -8422,19 +8424,9 @@ again_one_more_time:
sctp_move_chunks_from_net(stcb, net);
}
*reason_code = 7;
- continue;
- } else
+ break;
+ } else {
asoc->ifp_had_enobuf = 0;
- /* Only HB or ASCONF advances time */
- if (hbflag) {
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
- }
- hbflag = 0;
}
/*
* increase the number we sent, if a
@@ -8468,6 +8460,10 @@ again_one_more_time:
}
}
}
+ if (error != 0) {
+ /* try next net */
+ continue;
+ }
/* JRI: if dest is in PF state, do not send data to it */
if ((asoc->sctp_cmt_on_off > 0) &&
(net != stcb->asoc.alternate) &&
@@ -8512,16 +8508,16 @@ again_one_more_time:
switch (((struct sockaddr *)&net->ro._l_addr)->sa_family) {
#ifdef INET
case AF_INET:
- if (net->mtu > (sizeof(struct ip) + sizeof(struct sctphdr)))
- omtu = net->mtu - (sizeof(struct ip) + sizeof(struct sctphdr));
+ if (net->mtu > SCTP_MIN_V4_OVERHEAD)
+ omtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
else
omtu = 0;
break;
#endif
#ifdef INET6
case AF_INET6:
- if (net->mtu > (sizeof(struct ip6_hdr) + sizeof(struct sctphdr)))
- omtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
+ if (net->mtu > SCTP_MIN_OVERHEAD)
+ omtu = net->mtu - SCTP_MIN_OVERHEAD;
else
omtu = 0;
break;
@@ -8531,7 +8527,8 @@ again_one_more_time:
omtu = 0;
break;
}
- if ((((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) &&
+ if ((((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
+ (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) &&
(skip_data_for_this_net == 0)) ||
(cookie)) {
TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
@@ -8721,6 +8718,14 @@ no_data_fill:
*/
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
}
+ if (bundle_at || hbflag) {
+ /* For data/asconf and hb set time */
+ if (*now_filled == 0) {
+ (void)SCTP_GETTIME_TIMEVAL(now);
+ *now_filled = 1;
+ }
+ net->last_sent_time = *now;
+ }
/* Now send it, if there is anything to send :> */
if ((error = sctp_lowlevel_chunk_output(inp,
stcb,
@@ -8739,23 +8744,13 @@ no_data_fill:
0, 0,
so_locked))) {
/* error, we could not output */
- if (error == ENOBUFS) {
- SCTP_STAT_INCR(sctps_lowlevelerr);
- asoc->ifp_had_enobuf = 1;
- }
+ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
}
- SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
- if (hbflag) {
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
- }
- hbflag = 0;
+ if (error == ENOBUFS) {
+ SCTP_STAT_INCR(sctps_lowlevelerr);
+ asoc->ifp_had_enobuf = 1;
}
if (error == EHOSTUNREACH) {
/*
@@ -8780,16 +8775,6 @@ no_data_fill:
endoutchain = NULL;
auth = NULL;
auth_offset = 0;
- if (bundle_at || hbflag) {
- /* For data/asconf and hb set time */
- if (*now_filled == 0) {
- (void)SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
- *now_filled = 1;
- *now = net->last_sent_time;
- } else {
- net->last_sent_time = *now;
- }
- }
if (!no_out_cnt) {
*num_out += (ctl_cnt + bundle_at);
}
@@ -9780,7 +9765,7 @@ one_chunk_around:
* t3-expiring.
*/
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, inp, stcb, net,
- SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_4);
+ SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_2);
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
}
}
@@ -10387,7 +10372,8 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked
/* No memory so we drop the idea, and set a timer */
if (stcb->asoc.delayed_ack) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
+ stcb->sctp_ep, stcb, NULL,
+ SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_3);
sctp_timer_start(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL);
} else {
@@ -10455,7 +10441,8 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked
/* sa_ignore NO_NULL_CHK */
if (stcb->asoc.delayed_ack) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
- stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6);
+ stcb->sctp_ep, stcb, NULL,
+ SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_4);
sctp_timer_start(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL);
} else {
@@ -11996,9 +11983,6 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp,
struct uio *uio,
int resv_upfront)
{
- int left;
-
- left = sp->length;
sp->data = m_uiotombuf(uio, M_WAITOK, sp->length,
resv_upfront, 0);
if (sp->data == NULL) {
@@ -12427,7 +12411,8 @@ sctp_lower_sosend(struct socket *so,
if (control) {
if (sctp_process_cmsgs_for_init(stcb, control, &error)) {
- sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_7);
+ sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE,
+ SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
hold_tcblock = 0;
stcb = NULL;
goto out_unlocked;
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 6edf33afc986..6fcb6d2eebe3 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -3544,7 +3544,8 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
(SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
- if (sctp_free_assoc(inp, asoc, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_PCB + SCTP_LOC_8) == 0) {
+ if (sctp_free_assoc(inp, asoc, SCTP_PCBFREE_FORCE,
+ SCTP_FROM_SCTP_PCB + SCTP_LOC_8) == 0) {
cnt++;
}
}
@@ -3791,13 +3792,9 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
/* assure len is set */
sin->sin_len = sizeof(struct sockaddr_in);
if (set_scope) {
-#ifdef SCTP_DONT_DO_PRIVADDR_SCOPE
- stcb->asoc.scope.ipv4_local_scope = 1;
-#else
if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
stcb->asoc.scope.ipv4_local_scope = 1;
}
-#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
} else {
/* Validate the address is in scope */
if ((IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) &&
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index 285d7fb3f9b4..bb22c2747681 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -418,6 +418,7 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
xinpcb.total_recvs = inp->total_recvs;
xinpcb.total_nospaces = inp->total_nospaces;
xinpcb.fragmentation_point = inp->sctp_frag_point;
+ xinpcb.socket = inp->sctp_socket;
so = inp->sctp_socket;
if ((so == NULL) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) {
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index d8422b901747..257d18845b23 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -110,7 +110,9 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
net->dest_state |= SCTP_ADDR_PF;
net->last_active = sctp_get_tick_count();
sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
}
}
@@ -153,7 +155,7 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
"Association error counter exceeded");
- inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_1;
+ inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_2;
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
return (1);
}
@@ -1046,7 +1048,7 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
"Cookie timer expired, but no cookie");
- inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_4;
+ inp->last_abort_code = SCTP_FROM_SCTP_TIMER + SCTP_LOC_3;
sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
} else {
#ifdef INVARIANTS
diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h
index d22b9d121e84..fd78d3493e02 100644
--- a/sys/netinet/sctp_uio.h
+++ b/sys/netinet/sctp_uio.h
@@ -1165,7 +1165,12 @@ struct xsctp_inpcb {
uint16_t local_port;
uint16_t qlen;
uint16_t maxqlen;
- uint32_t extra_padding[31]; /* future */
+ void *socket;
+#if defined(__LP64__)
+ uint32_t extra_padding[29]; /* future */
+#else
+ uint32_t extra_padding[30]; /* future */
+#endif
};
struct xsctp_tcb {
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index d2529695ea33..3d06a52cfb59 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -288,7 +288,8 @@ sctp_notify(struct sctp_inpcb *inp,
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
/* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed. */
@@ -777,7 +778,8 @@ sctp_disconnect(struct socket *so)
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_3);
/* No unlock tcb assoc is gone */
return (0);
}
@@ -862,7 +864,8 @@ sctp_disconnect(struct socket *so)
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
SCTP_INP_RUNLOCK(inp);
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_5);
return (0);
} else {
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CLOSING, SCTP_SO_LOCKED);
@@ -1562,7 +1565,8 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
sctp_connectx_helper_add(stcb, sa, (totaddr - 1), &error);
/* Fill in the return id */
if (error) {
- (void)sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6);
+ (void)sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7);
goto out_now;
}
a_id = (sctp_assoc_t *) optval;
@@ -2435,17 +2439,23 @@ flags_out:
/* Applies to the specific association */
paddrp->spp_flags = 0;
if (net != NULL) {
- int ovh;
-
- if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
- ovh = SCTP_MED_OVERHEAD;
- } else {
- ovh = SCTP_MED_V4_OVERHEAD;
- }
-
paddrp->spp_hbinterval = net->heart_beat_delay;
paddrp->spp_pathmaxrxt = net->failure_threshold;
- paddrp->spp_pathmtu = net->mtu - ovh;
+ paddrp->spp_pathmtu = net->mtu;
+ switch (net->ro._l_addr.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ paddrp->spp_pathmtu -= SCTP_MIN_V4_OVERHEAD;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ paddrp->spp_pathmtu -= SCTP_MIN_V4_OVERHEAD;
+ break;
+#endif
+ default:
+ break;
+ }
/* get flags for HB */
if (net->dest_state & SCTP_ADDR_NOHB) {
paddrp->spp_flags |= SPP_HB_DISABLE;
@@ -2454,9 +2464,9 @@ flags_out:
}
/* get flags for PMTU */
if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
- paddrp->spp_flags |= SPP_PMTUD_ENABLE;
- } else {
paddrp->spp_flags |= SPP_PMTUD_DISABLE;
+ } else {
+ paddrp->spp_flags |= SPP_PMTUD_ENABLE;
}
if (net->dscp & 0x01) {
paddrp->spp_dscp = net->dscp & 0xfc;
@@ -2475,7 +2485,7 @@ flags_out:
* value
*/
paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
- paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc);
+ paddrp->spp_pathmtu = 0;
if (stcb->asoc.default_dscp & 0x01) {
paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc;
paddrp->spp_flags |= SPP_DSCP;
@@ -2611,6 +2621,20 @@ flags_out:
paddri->spinfo_rto = net->RTO;
paddri->spinfo_assoc_id = sctp_get_associd(stcb);
paddri->spinfo_mtu = net->mtu;
+ switch (addr->sa_family) {
+#if defined(INET)
+ case AF_INET:
+ paddri->spinfo_mtu -= SCTP_MIN_V4_OVERHEAD;
+ break;
+#endif
+#if defined(INET6)
+ case AF_INET6:
+ paddri->spinfo_mtu -= SCTP_MIN_OVERHEAD;
+ break;
+#endif
+ default:
+ break;
+ }
SCTP_TCB_UNLOCK(stcb);
*optsize = sizeof(struct sctp_paddrinfo);
} else {
@@ -2687,6 +2711,20 @@ flags_out:
sstat->sstat_primary.spinfo_srtt = net->lastsa >> SCTP_RTT_SHIFT;
sstat->sstat_primary.spinfo_rto = net->RTO;
sstat->sstat_primary.spinfo_mtu = net->mtu;
+ switch (stcb->asoc.primary_destination->ro._l_addr.sa.sa_family) {
+#if defined(INET)
+ case AF_INET:
+ sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_V4_OVERHEAD;
+ break;
+#endif
+#if defined(INET6)
+ case AF_INET6:
+ sstat->sstat_primary.spinfo_mtu -= SCTP_MIN_OVERHEAD;
+ break;
+#endif
+ default:
+ break;
+ }
sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
SCTP_TCB_UNLOCK(stcb);
*optsize = sizeof(struct sctp_status);
@@ -4785,7 +4823,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb,
stcb->asoc.primary_destination,
- SCTP_FROM_SCTP_USRREQ + SCTP_LOC_9);
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
} else {
/*
@@ -5184,26 +5222,13 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
if (stcb != NULL) {
/************************TCB SPECIFIC SET ******************/
- /*
- * do we change the timer for HB, we run
- * only one?
- */
- int ovh = 0;
-
- if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
- ovh = SCTP_MED_OVERHEAD;
- } else {
- ovh = SCTP_MED_V4_OVERHEAD;
- }
-
- /* network sets ? */
if (net != NULL) {
/************************NET SPECIFIC SET ******************/
if (paddrp->spp_flags & SPP_HB_DISABLE) {
if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED) &&
!(net->dest_state & SCTP_ADDR_NOHB)) {
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
- SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_9);
}
net->dest_state |= SCTP_ADDR_NOHB;
}
@@ -5227,10 +5252,24 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) {
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
- SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_11);
}
net->dest_state |= SCTP_ADDR_NO_PMTUD;
- net->mtu = paddrp->spp_pathmtu + ovh;
+ net->mtu = paddrp->spp_pathmtu;
+ switch (net->ro._l_addr.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ net->mtu += SCTP_MIN_V4_OVERHEAD;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ net->mtu += SCTP_MIN_OVERHEAD;
+ break;
+#endif
+ default:
+ break;
+ }
if (net->mtu < stcb->asoc.smallest_mtu) {
sctp_pathmtu_adjustment(stcb, net->mtu);
}
@@ -5251,7 +5290,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
(net->error_count > net->pf_threshold)) {
net->dest_state |= SCTP_ADDR_PF;
sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_12);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
}
}
@@ -5294,7 +5335,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
(net->error_count > net->pf_threshold)) {
net->dest_state |= SCTP_ADDR_PF;
sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_13);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
}
}
@@ -5329,7 +5372,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
net->dest_state &= ~SCTP_ADDR_NOHB;
}
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net,
- SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_14);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
}
sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
@@ -5339,7 +5382,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
if (!(net->dest_state & SCTP_ADDR_NOHB)) {
net->dest_state |= SCTP_ADDR_NOHB;
if (!(net->dest_state & SCTP_ADDR_UNCONFIRMED)) {
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
+ inp, stcb, net,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_15);
}
}
}
@@ -5349,10 +5394,24 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
- SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_16);
}
net->dest_state |= SCTP_ADDR_NO_PMTUD;
- net->mtu = paddrp->spp_pathmtu + ovh;
+ net->mtu = paddrp->spp_pathmtu;
+ switch (net->ro._l_addr.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ net->mtu += SCTP_MIN_V4_OVERHEAD;
+ break;
+#endif
+#ifdef INET6
+ case AF_INET6:
+ net->mtu += SCTP_MIN_OVERHEAD;
+ break;
+#endif
+ default:
+ break;
+ }
if (net->mtu < stcb->asoc.smallest_mtu) {
sctp_pathmtu_adjustment(stcb, net->mtu);
}
@@ -6199,7 +6258,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
(net->error_count <= net->failure_threshold)) {
net->dest_state |= SCTP_ADDR_PF;
sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_17);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
}
}
@@ -6228,7 +6289,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
(net->error_count <= net->failure_threshold)) {
net->dest_state |= SCTP_ADDR_PF;
sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
- sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT,
+ stcb->sctp_ep, stcb, net,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_18);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
}
}
@@ -7127,7 +7190,8 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
}
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
SCTP_TCB_LOCK(stcb);
- sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7);
+ sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_19);
}
return (0);
}
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index a30a9425a6a4..24110dd1ce89 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1449,7 +1449,7 @@ sctp_timeout_handler(void *t)
struct socket *so;
#endif
- int did_output, type;
+ int did_output;
tmr = (struct sctp_timer *)t;
inp = (struct sctp_inpcb *)tmr->ep;
@@ -1488,7 +1488,6 @@ sctp_timeout_handler(void *t)
}
/* if this is an iterator timeout, get the struct and clear inp */
tmr->stopped_from = 0xa003;
- type = tmr->type;
if (inp) {
SCTP_INP_INCR_REF(inp);
if ((inp->sctp_socket == NULL) &&
@@ -1809,7 +1808,8 @@ sctp_timeout_handler(void *t)
SCTP_STAT_INCR(sctps_timoassockill);
/* Can we free it yet? */
SCTP_INP_DECR_REF(inp);
- sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_1);
+ sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_1);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
so = SCTP_INP_SO(inp);
atomic_add_int(&stcb->asoc.refcnt, 1);
@@ -1818,7 +1818,8 @@ sctp_timeout_handler(void *t)
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_2);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_2);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -1838,7 +1839,8 @@ sctp_timeout_handler(void *t)
* killer
*/
SCTP_INP_DECR_REF(inp);
- sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_3);
+ sctp_timer_stop(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_3);
sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
SCTP_CALLED_FROM_INPKILL_TIMER);
inp = NULL;
@@ -1873,7 +1875,7 @@ out_decr:
}
out_no_decr:
SCTPDBG(SCTP_DEBUG_TIMER1, "Timer now complete (type %d)\n",
- type);
+ tmr->type);
CURVNET_RESTORE();
}
@@ -3910,7 +3912,8 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
(SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_4);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_4);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
#endif
@@ -4034,7 +4037,8 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
atomic_subtract_int(&stcb->asoc.refcnt, 1);
}
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_5);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_5);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
if (!so_locked) {
SCTP_SOCKET_UNLOCK(so, 1);
@@ -5165,7 +5169,8 @@ sctp_user_rcvd(struct sctp_tcb *stcb, uint32_t * freed_so_far, int hold_rlock,
sctp_chunk_output(stcb->sctp_ep, stcb,
SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
/* make sure no timer is running */
- sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
+ sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
SCTP_TCB_UNLOCK(stcb);
} else {
/* Update how much we have pending */
@@ -6323,14 +6328,16 @@ sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
(sin->sin_addr.s_addr == INADDR_BROADCAST) ||
IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_7);
*error = EINVAL;
goto out_now;
}
if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
/* assoc gone no un-lock */
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_8);
*error = ENOBUFS;
goto out_now;
}
@@ -6344,14 +6351,16 @@ sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_9);
*error = EINVAL;
goto out_now;
}
if (sctp_add_remote_addr(stcb, sa, NULL, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
/* assoc gone no un-lock */
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTPUTIL + SCTP_LOC_10);
*error = ENOBUFS;
goto out_now;
}
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index a64e403eb179..d992492cddc7 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -347,11 +347,12 @@ tcp_timer_2msl(void *xtp)
tp = tcp_close(tp);
} else {
if (tp->t_state != TCPS_TIME_WAIT &&
- ticks - tp->t_rcvtime <= TP_MAXIDLE(tp))
- callout_reset_on(&tp->t_timers->tt_2msl,
- TP_KEEPINTVL(tp), tcp_timer_2msl, tp,
- inp_to_cpuid(inp));
- else
+ ticks - tp->t_rcvtime <= TP_MAXIDLE(tp)) {
+ if (!callout_reset(&tp->t_timers->tt_2msl,
+ TP_KEEPINTVL(tp), tcp_timer_2msl, tp)) {
+ tp->t_timers->tt_flags &= ~TT_2MSL_RST;
+ }
+ } else
tp = tcp_close(tp);
}
@@ -431,11 +432,14 @@ tcp_timer_keep(void *xtp)
tp->rcv_nxt, tp->snd_una - 1, 0);
free(t_template, M_TEMP);
}
- callout_reset_on(&tp->t_timers->tt_keep, TP_KEEPINTVL(tp),
- tcp_timer_keep, tp, inp_to_cpuid(inp));
- } else
- callout_reset_on(&tp->t_timers->tt_keep, TP_KEEPIDLE(tp),
- tcp_timer_keep, tp, inp_to_cpuid(inp));
+ if (!callout_reset(&tp->t_timers->tt_keep, TP_KEEPINTVL(tp),
+ tcp_timer_keep, tp)) {
+ tp->t_timers->tt_flags &= ~TT_KEEP_RST;
+ }
+ } else if (!callout_reset(&tp->t_timers->tt_keep, TP_KEEPIDLE(tp),
+ tcp_timer_keep, tp)) {
+ tp->t_timers->tt_flags &= ~TT_KEEP_RST;
+ }
#ifdef TCPDEBUG
if (inp->inp_socket->so_options & SO_DEBUG)
@@ -810,6 +814,7 @@ tcp_timer_activate(struct tcpcb *tp, uint32_t timer_type, u_int delta)
timeout_t *f_callout;
struct inpcb *inp = tp->t_inpcb;
int cpu = inp_to_cpuid(inp);
+ uint32_t f_reset;
#ifdef TCP_OFFLOAD
if (tp->t_flags & TF_TOE)
@@ -823,38 +828,49 @@ tcp_timer_activate(struct tcpcb *tp, uint32_t timer_type, u_int delta)
case TT_DELACK:
t_callout = &tp->t_timers->tt_delack;
f_callout = tcp_timer_delack;
+ f_reset = TT_DELACK_RST;
break;
case TT_REXMT:
t_callout = &tp->t_timers->tt_rexmt;
f_callout = tcp_timer_rexmt;
+ f_reset = TT_REXMT_RST;
break;
case TT_PERSIST:
t_callout = &tp->t_timers->tt_persist;
f_callout = tcp_timer_persist;
+ f_reset = TT_PERSIST_RST;
break;
case TT_KEEP:
t_callout = &tp->t_timers->tt_keep;
f_callout = tcp_timer_keep;
+ f_reset = TT_KEEP_RST;
break;
case TT_2MSL:
t_callout = &tp->t_timers->tt_2msl;
f_callout = tcp_timer_2msl;
+ f_reset = TT_2MSL_RST;
break;
default:
panic("tp %p bad timer_type %#x", tp, timer_type);
}
if (delta == 0) {
if ((tp->t_timers->tt_flags & timer_type) &&
- callout_stop(t_callout)) {
- tp->t_timers->tt_flags &= ~timer_type;
+ callout_stop(t_callout) &&
+ (tp->t_timers->tt_flags & f_reset)) {
+ tp->t_timers->tt_flags &= ~(timer_type | f_reset);
}
} else {
if ((tp->t_timers->tt_flags & timer_type) == 0) {
- tp->t_timers->tt_flags |= timer_type;
+ tp->t_timers->tt_flags |= (timer_type | f_reset);
callout_reset_on(t_callout, delta, f_callout, tp, cpu);
} else {
/* Reset already running callout on the same CPU. */
- callout_reset(t_callout, delta, f_callout, tp);
+ if (!callout_reset(t_callout, delta, f_callout, tp)) {
+ /*
+ * Callout not cancelled, consider it as not
+ * properly restarted. */
+ tp->t_timers->tt_flags &= ~f_reset;
+ }
}
}
}
@@ -891,6 +907,7 @@ tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type)
{
struct callout *t_callout;
timeout_t *f_callout;
+ uint32_t f_reset;
tp->t_timers->tt_flags |= TT_STOPPED;
@@ -898,30 +915,36 @@ tcp_timer_stop(struct tcpcb *tp, uint32_t timer_type)
case TT_DELACK:
t_callout = &tp->t_timers->tt_delack;
f_callout = tcp_timer_delack_discard;
+ f_reset = TT_DELACK_RST;
break;
case TT_REXMT:
t_callout = &tp->t_timers->tt_rexmt;
f_callout = tcp_timer_rexmt_discard;
+ f_reset = TT_REXMT_RST;
break;
case TT_PERSIST:
t_callout = &tp->t_timers->tt_persist;
f_callout = tcp_timer_persist_discard;
+ f_reset = TT_PERSIST_RST;
break;
case TT_KEEP:
t_callout = &tp->t_timers->tt_keep;
f_callout = tcp_timer_keep_discard;
+ f_reset = TT_KEEP_RST;
break;
case TT_2MSL:
t_callout = &tp->t_timers->tt_2msl;
f_callout = tcp_timer_2msl_discard;
+ f_reset = TT_2MSL_RST;
break;
default:
panic("tp %p bad timer_type %#x", tp, timer_type);
}
if (tp->t_timers->tt_flags & timer_type) {
- if (callout_stop(t_callout)) {
- tp->t_timers->tt_flags &= ~timer_type;
+ if (callout_stop(t_callout) &&
+ (tp->t_timers->tt_flags & f_reset)) {
+ tp->t_timers->tt_flags &= ~(timer_type | f_reset);
} else {
/*
* Can't stop the callout, defer tcpcb actual deletion
diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h
index 02a7782f2b78..dbb8aee1a415 100644
--- a/sys/netinet/tcp_timer.h
+++ b/sys/netinet/tcp_timer.h
@@ -160,6 +160,12 @@ struct tcp_timer {
#define TT_2MSL 0x0010
#define TT_MASK (TT_DELACK|TT_REXMT|TT_PERSIST|TT_KEEP|TT_2MSL)
+#define TT_DELACK_RST 0x0100
+#define TT_REXMT_RST 0x0200
+#define TT_PERSIST_RST 0x0400
+#define TT_KEEP_RST 0x0800
+#define TT_2MSL_RST 0x1000
+
#define TT_STOPPED 0x00010000
#define TP_KEEPINIT(tp) ((tp)->t_keepinit ? (tp)->t_keepinit : tcp_keepinit)
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index d2570c4a2b1b..fe98f0c8c51c 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1279,6 +1279,7 @@ in6_broadcast_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
nd6_dad_start((struct ifaddr *)ia, delay);
}
+ in6_newaddrmsg(ia, RTM_ADD);
ifa_free(&ia->ia_ifa);
return (error);
}
@@ -1327,6 +1328,7 @@ in6_purgeaddr(struct ifaddr *ifa)
ia->ia_flags &= ~IFA_ROUTE;
}
+ in6_newaddrmsg(ia, RTM_DELETE);
in6_unlink_ifa(ia, ifp);
}
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 83dda1a18427..daac188f5812 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -2185,7 +2185,6 @@ nd6_add_ifa_lle(struct in6_ifaddr *ia)
ln->la_expire = 0; /* for IPv6 this means permanent */
ln->ln_state = ND6_LLINFO_REACHABLE;
LLE_WUNLOCK(ln);
- in6_newaddrmsg(ia, RTM_ADD);
return (0);
}
@@ -2205,8 +2204,6 @@ nd6_rem_ifa_lle(struct in6_ifaddr *ia)
struct sockaddr_in6 mask, addr;
struct ifnet *ifp;
- in6_newaddrmsg(ia, RTM_DELETE);
-
ifp = ia->ia_ifa.ifa_ifp;
memcpy(&addr, &ia->ia_addr, sizeof(ia->ia_addr));
memcpy(&mask, &ia->ia_prefixmask, sizeof(ia->ia_prefixmask));
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index f2b2322ee4bc..54c65b61b9e6 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -211,7 +211,8 @@ sctp6_notify_mbuf(struct sctp_inpcb *inp, struct icmp6_hdr *icmp6,
*/
nxtsz = ntohl(icmp6->icmp6_mtu);
/* Stop any PMTU timer */
- sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL, SCTP_FROM_SCTP6_USRREQ + SCTP_LOC_1);
+ sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL,
+ SCTP_FROM_SCTP6_USRREQ + SCTP_LOC_1);
/* Adjust destination size limit */
if (net->mtu > nxtsz) {
@@ -333,7 +334,8 @@ sctp6_notify(struct sctp_inpcb *inp,
SCTP_TCB_LOCK(stcb);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
#endif
- (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_2);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP6_USRREQ + SCTP_LOC_2);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_SOCKET_UNLOCK(so, 1);
/* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed. */
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index 1e70fb274f0b..b6c6a6ae0cbf 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -7714,14 +7714,6 @@ key_sa_chgstate(struct secasvar *sav, u_int8_t state)
}
}
-void
-key_sa_stir_iv(struct secasvar *sav)
-{
-
- IPSEC_ASSERT(sav->iv != NULL, ("null IV"));
- key_randomfill(sav->iv, sav->ivlen);
-}
-
/*
* Take one of the kernel's security keys and convert it into a PF_KEY
* structure within an mbuf, suitable for sending up to a waiting
diff --git a/sys/netipsec/key.h b/sys/netipsec/key.h
index 29abb800428f..82811be0e5da 100644
--- a/sys/netipsec/key.h
+++ b/sys/netipsec/key.h
@@ -105,7 +105,6 @@ extern void key_init(void);
extern void key_destroy(void);
#endif
extern void key_sa_recordxfer(struct secasvar *, struct mbuf *);
-extern void key_sa_stir_iv(struct secasvar *);
#ifdef IPSEC_NAT_T
u_int16_t key_portfromsaddr(struct sockaddr *);
#define KEY_PORTFROMSADDR(saddr) \
diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c
index 3f210c29df70..384f5653bdec 100644
--- a/sys/netpfil/pf/pf_norm.c
+++ b/sys/netpfil/pf/pf_norm.c
@@ -76,7 +76,6 @@ struct pf_fragment_cmp {
uint32_t frc_id;
sa_family_t frc_af;
uint8_t frc_proto;
- uint8_t frc_direction;
};
struct pf_fragment {
@@ -86,7 +85,6 @@ struct pf_fragment {
#define fr_id fr_key.frc_id
#define fr_af fr_key.frc_af
#define fr_proto fr_key.frc_proto
-#define fr_direction fr_key.frc_direction
RB_ENTRY(pf_fragment) fr_entry;
TAILQ_ENTRY(pf_fragment) frag_next;
@@ -157,7 +155,7 @@ static struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
#endif /* INET */
#ifdef INET6
static int pf_reassemble6(struct mbuf **, struct ip6_hdr *,
- struct ip6_frag *, uint16_t, uint16_t, int, u_short *);
+ struct ip6_frag *, uint16_t, uint16_t, u_short *);
static void pf_scrub_ip6(struct mbuf **, uint8_t);
#endif /* INET6 */
@@ -178,7 +176,6 @@ pf_ip2key(struct ip *ip, int dir, struct pf_fragment_cmp *key)
key->frc_af = AF_INET;
key->frc_proto = ip->ip_p;
key->frc_id = ip->ip_id;
- key->frc_direction = dir;
}
#endif /* INET */
@@ -663,7 +660,7 @@ pf_reassemble(struct mbuf **m0, struct ip *ip, int dir, u_short *reason)
#ifdef INET6
static int
pf_reassemble6(struct mbuf **m0, struct ip6_hdr *ip6, struct ip6_frag *fraghdr,
- uint16_t hdrlen, uint16_t extoff, int dir, u_short *reason)
+ uint16_t hdrlen, uint16_t extoff, u_short *reason)
{
struct mbuf *m = *m0;
struct pf_frent *frent;
@@ -697,7 +694,6 @@ pf_reassemble6(struct mbuf **m0, struct ip6_hdr *ip6, struct ip6_frag *fraghdr,
/* Only the first fragment's protocol is relevant. */
key.frc_proto = 0;
key.frc_id = fraghdr->ip6f_ident;
- key.frc_direction = dir;
if ((frag = pf_fillup_fragment(&key, frent, reason)) == NULL) {
PF_FRAG_UNLOCK();
@@ -823,6 +819,8 @@ pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
(*frag)->fr_max = 0;
(*frag)->fr_src.v4 = h->ip_src;
(*frag)->fr_dst.v4 = h->ip_dst;
+ (*frag)->fr_af = AF_INET;
+ (*frag)->fr_proto = h->ip_p;
(*frag)->fr_id = h->ip_id;
(*frag)->fr_timeout = time_uptime;
@@ -1553,7 +1551,7 @@ pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
off += sizeof(frag);
/* Returns PF_DROP or *m0 is NULL or completely reassembled mbuf. */
- if (pf_reassemble6(m0, h, &frag, off, extoff, dir, reason) != PF_PASS)
+ if (pf_reassemble6(m0, h, &frag, off, extoff, reason) != PF_PASS)
return (PF_DROP);
m = *m0;
if (m == NULL)
diff --git a/sys/ofed/drivers/infiniband/core/umem.c b/sys/ofed/drivers/infiniband/core/umem.c
index cdd2e67fa248..5f4465f97165 100644
--- a/sys/ofed/drivers/infiniband/core/umem.c
+++ b/sys/ofed/drivers/infiniband/core/umem.c
@@ -272,7 +272,7 @@ struct ib_umem *ib_umem_get_ex(struct ib_ucontext *context, unsigned long addr,
PROC_LOCK(proc);
if (ptoa(npages +
pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) >
- lim_cur(proc, RLIMIT_MEMLOCK)) {
+ lim_cur_proc(proc, RLIMIT_MEMLOCK)) {
PROC_UNLOCK(proc);
kfree(umem);
return ERR_PTR(-ENOMEM);
diff --git a/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c b/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c
index 0cdebaf17268..ad5818ee303a 100644
--- a/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/sys/ofed/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -553,7 +553,8 @@ out:
proc = curproc;
pmap = vm_map_pmap(&proc->p_vmspace->vm_map);
PROC_LOCK(proc);
- if (ptoa(pmap_wired_count(pmap) + 1) > lim_cur(proc, RLIMIT_MEMLOCK)) {
+ if (ptoa(pmap_wired_count(pmap) + 1) >
+ lim_cur_proc(proc, RLIMIT_MEMLOCK)) {
PROC_UNLOCK(proc);
ret = -ENOMEM;
goto out;
diff --git a/sys/ofed/drivers/net/mlx4/en_netdev.c b/sys/ofed/drivers/net/mlx4/en_netdev.c
index 5988c0da4c59..d8b2f4fbdea0 100644
--- a/sys/ofed/drivers/net/mlx4/en_netdev.c
+++ b/sys/ofed/drivers/net/mlx4/en_netdev.c
@@ -1967,6 +1967,29 @@ static int mlx4_en_ioctl(struct ifnet *dev, u_long command, caddr_t data)
mutex_unlock(&mdev->state_lock);
VLAN_CAPABILITIES(dev);
break;
+ case SIOCGI2C: {
+ struct ifi2creq i2c;
+
+ error = copyin(ifr->ifr_data, &i2c, sizeof(i2c));
+ if (error)
+ break;
+ if (i2c.len > sizeof(i2c.data)) {
+ error = EINVAL;
+ break;
+ }
+ /*
+ * Note that we ignore i2c.addr here. The driver hardcodes
+ * the address to 0x50, while standard expects it to be 0xA0.
+ */
+ error = mlx4_get_module_info(mdev->dev, priv->port,
+ i2c.offset, i2c.len, i2c.data);
+ if (error < 0) {
+ error = -error;
+ break;
+ }
+ error = copyout(&i2c, ifr->ifr_data, sizeof(i2c));
+ break;
+ }
default:
error = ether_ioctl(dev, command, data);
break;
diff --git a/sys/ofed/drivers/net/mlx4/port.c b/sys/ofed/drivers/net/mlx4/port.c
index c653d4ba35c2..4d7aa0ba90e5 100644
--- a/sys/ofed/drivers/net/mlx4/port.c
+++ b/sys/ofed/drivers/net/mlx4/port.c
@@ -1058,3 +1058,160 @@ int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id, u
}
EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave);
+/* Cable Module Info */
+#define MODULE_INFO_MAX_READ 48
+
+#define I2C_ADDR_LOW 0x50
+#define I2C_ADDR_HIGH 0x51
+#define I2C_PAGE_SIZE 256
+
+/* Module Info Data */
+struct mlx4_cable_info {
+ u8 i2c_addr;
+ u8 page_num;
+ __be16 dev_mem_address;
+ __be16 reserved1;
+ __be16 size;
+ __be32 reserved2[2];
+ u8 data[MODULE_INFO_MAX_READ];
+};
+
+enum cable_info_err {
+ CABLE_INF_INV_PORT = 0x1,
+ CABLE_INF_OP_NOSUP = 0x2,
+ CABLE_INF_NOT_CONN = 0x3,
+ CABLE_INF_NO_EEPRM = 0x4,
+ CABLE_INF_PAGE_ERR = 0x5,
+ CABLE_INF_INV_ADDR = 0x6,
+ CABLE_INF_I2C_ADDR = 0x7,
+ CABLE_INF_QSFP_VIO = 0x8,
+ CABLE_INF_I2C_BUSY = 0x9,
+};
+
+#define MAD_STATUS_2_CABLE_ERR(mad_status) ((mad_status >> 8) & 0xFF)
+
+#ifdef DEBUG
+static inline const char *cable_info_mad_err_str(u16 mad_status)
+{
+ u8 err = MAD_STATUS_2_CABLE_ERR(mad_status);
+
+ switch (err) {
+ case CABLE_INF_INV_PORT:
+ return "invalid port selected";
+ case CABLE_INF_OP_NOSUP:
+ return "operation not supported for this port (the port is of type CX4 or internal)";
+ case CABLE_INF_NOT_CONN:
+ return "cable is not connected";
+ case CABLE_INF_NO_EEPRM:
+ return "the connected cable has no EPROM (passive copper cable)";
+ case CABLE_INF_PAGE_ERR:
+ return "page number is greater than 15";
+ case CABLE_INF_INV_ADDR:
+ return "invalid device_address or size (that is, size equals 0 or address+size is greater than 256)";
+ case CABLE_INF_I2C_ADDR:
+ return "invalid I2C slave address";
+ case CABLE_INF_QSFP_VIO:
+ return "at least one cable violates the QSFP specification and ignores the modsel signal";
+ case CABLE_INF_I2C_BUSY:
+ return "I2C bus is constantly busy";
+ }
+ return "Unknown Error";
+}
+#endif /* DEBUG */
+
+/**
+ * mlx4_get_module_info - Read cable module eeprom data
+ * @dev: mlx4_dev.
+ * @port: port number.
+ * @offset: byte offset in eeprom to start reading data from.
+ * @size: num of bytes to read.
+ * @data: output buffer to put the requested data into.
+ *
+ * Reads cable module eeprom data, puts the outcome data into
+ * data pointer paramer.
+ * Returns num of read bytes on success or a negative error
+ * code.
+ */
+int mlx4_get_module_info(struct mlx4_dev *dev, u8 port, u16 offset,
+ u16 size, u8 *data)
+{
+ struct mlx4_cmd_mailbox *inbox, *outbox;
+ struct mlx4_mad_ifc *inmad, *outmad;
+ struct mlx4_cable_info *cable_info;
+ u16 i2c_addr;
+ int ret;
+
+ if (size > MODULE_INFO_MAX_READ)
+ size = MODULE_INFO_MAX_READ;
+
+ inbox = mlx4_alloc_cmd_mailbox(dev);
+ if (IS_ERR(inbox))
+ return PTR_ERR(inbox);
+
+ outbox = mlx4_alloc_cmd_mailbox(dev);
+ if (IS_ERR(outbox)) {
+ mlx4_free_cmd_mailbox(dev, inbox);
+ return PTR_ERR(outbox);
+ }
+
+ inmad = (struct mlx4_mad_ifc *)(inbox->buf);
+ outmad = (struct mlx4_mad_ifc *)(outbox->buf);
+
+ inmad->method = 0x1; /* Get */
+ inmad->class_version = 0x1;
+ inmad->mgmt_class = 0x1;
+ inmad->base_version = 0x1;
+ inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */
+
+ if (offset < I2C_PAGE_SIZE && offset + size > I2C_PAGE_SIZE)
+ /* Cross pages reads are not allowed
+ * read until offset 256 in low page
+ */
+ size -= offset + size - I2C_PAGE_SIZE;
+
+ i2c_addr = I2C_ADDR_LOW;
+ if (offset >= I2C_PAGE_SIZE) {
+ /* Reset offset to high page */
+ i2c_addr = I2C_ADDR_HIGH;
+ offset -= I2C_PAGE_SIZE;
+ }
+
+ cable_info = (struct mlx4_cable_info *)inmad->data;
+ cable_info->dev_mem_address = cpu_to_be16(offset);
+ cable_info->page_num = 0;
+ cable_info->i2c_addr = i2c_addr;
+ cable_info->size = cpu_to_be16(size);
+
+ ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3,
+ MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, MLX4_CMD_NATIVE);
+ if (ret)
+ goto out;
+
+ if (be16_to_cpu(outmad->status)) {
+ /* Mad returned with bad status */
+ ret = be16_to_cpu(outmad->status);
+#ifdef DEBUG
+ mlx4_warn(dev, "MLX4_CMD_MAD_IFC Get Module info attr(%x) "
+ "port(%d) i2c_addr(%x) offset(%d) size(%d): Response "
+ "Mad Status(%x) - %s\n", 0xFF60, port, i2c_addr, offset,
+ size, ret, cable_info_mad_err_str(ret));
+#endif
+ if (i2c_addr == I2C_ADDR_HIGH &&
+ MAD_STATUS_2_CABLE_ERR(ret) == CABLE_INF_I2C_ADDR)
+ /* Some SFP cables do not support i2c slave
+ * address 0x51 (high page), abort silently.
+ */
+ ret = 0;
+ else
+ ret = -ret;
+ goto out;
+ }
+ cable_info = (struct mlx4_cable_info *)outmad->data;
+ memcpy(data, cable_info->data, size);
+ ret = size;
+out:
+ mlx4_free_cmd_mailbox(dev, inbox);
+ mlx4_free_cmd_mailbox(dev, outbox);
+ return ret;
+}
+EXPORT_SYMBOL(mlx4_get_module_info);
diff --git a/sys/ofed/include/linux/mlx4/device.h b/sys/ofed/include/linux/mlx4/device.h
index 8c0db91f49ac..536c421132c7 100644
--- a/sys/ofed/include/linux/mlx4/device.h
+++ b/sys/ofed/include/linux/mlx4/device.h
@@ -892,6 +892,26 @@ struct mlx4_init_port_param {
u64 si_guid;
};
+#define MAD_IFC_DATA_SZ 192
+/* MAD IFC Mailbox */
+struct mlx4_mad_ifc {
+ u8 base_version;
+ u8 mgmt_class;
+ u8 class_version;
+ u8 method;
+ __be16 status;
+ __be16 class_specific;
+ __be64 tid;
+ __be16 attr_id;
+ __be16 resv;
+ __be32 attr_mod;
+ __be64 mkey;
+ __be16 dr_slid;
+ __be16 dr_dlid;
+ u8 reserved[28];
+ u8 data[MAD_IFC_DATA_SZ];
+} __packed;
+
#define mlx4_foreach_port(port, dev, type) \
for ((port) = 1; (port) <= (dev)->caps.num_ports; (port)++) \
if ((type) == (dev)->caps.port_mask[(port)])
@@ -1294,4 +1314,7 @@ int mlx4_read_clock(struct mlx4_dev *dev);
int mlx4_get_internal_clock_params(struct mlx4_dev *dev,
struct mlx4_clock_params *params);
+int mlx4_get_module_info(struct mlx4_dev *dev, u8 port,
+ u16 offset, u16 size, u8 *data);
+
#endif /* MLX4_DEVICE_H */
diff --git a/sys/opencrypto/cryptodeflate.c b/sys/opencrypto/cryptodeflate.c
index c55210dcbb78..28e284fce932 100644
--- a/sys/opencrypto/cryptodeflate.c
+++ b/sys/opencrypto/cryptodeflate.c
@@ -105,8 +105,8 @@ deflate_global(data, size, decomp, out)
bufh = bufp = malloc(sizeof(*bufp) + (size_t)(size * i),
M_CRYPTO_DATA, M_NOWAIT);
if (bufp == NULL) {
- SDT_PROBE3(opencrypto, deflate, deflate_global, bad,
- decomp, 0, __LINE__);
+ SDT_PROBE5(opencrypto, deflate, deflate_global, bad,
+ decomp, 0, __LINE__, 0, 0);
goto bad2;
}
bufp->next = NULL;
@@ -125,8 +125,8 @@ deflate_global(data, size, decomp, out)
deflateInit2(&zbuf, Z_DEFAULT_COMPRESSION, Z_METHOD,
window_deflate, Z_MEMLEVEL, Z_DEFAULT_STRATEGY);
if (error != Z_OK) {
- SDT_PROBE3(opencrypto, deflate, deflate_global, bad,
- decomp, error, __LINE__);
+ SDT_PROBE5(opencrypto, deflate, deflate_global, bad,
+ decomp, error, __LINE__, 0, 0);
goto bad;
}
@@ -165,8 +165,8 @@ deflate_global(data, size, decomp, out)
p = malloc(sizeof(*p) + (size_t)(size * i),
M_CRYPTO_DATA, M_NOWAIT);
if (p == NULL) {
- SDT_PROBE3(opencrypto, deflate, deflate_global,
- bad, decomp, 0, __LINE__);
+ SDT_PROBE5(opencrypto, deflate, deflate_global,
+ bad, decomp, 0, __LINE__, 0, 0);
goto bad;
}
p->next = NULL;
@@ -195,8 +195,8 @@ deflate_global(data, size, decomp, out)
*out = malloc(result, M_CRYPTO_DATA, M_NOWAIT);
if (*out == NULL) {
- SDT_PROBE3(opencrypto, deflate, deflate_global, bad,
- decomp, 0, __LINE__);
+ SDT_PROBE5(opencrypto, deflate, deflate_global, bad,
+ decomp, 0, __LINE__, 0, 0);
goto bad;
}
if (decomp)
diff --git a/sys/powerpc/conf/NOTES b/sys/powerpc/conf/NOTES
index 974c91ba00cd..9bfe6a956e04 100644
--- a/sys/powerpc/conf/NOTES
+++ b/sys/powerpc/conf/NOTES
@@ -3,6 +3,28 @@
# This file contains machine dependent kernel configuration notes. For
# machine independent notes, look in /sys/conf/NOTES.
+#
+# Enable the kernel DTrace hooks which are required to load the DTrace
+# kernel modules.
+#
+options KDTRACE_HOOKS
+
+# DTrace core
+# NOTE: introduces CDDL-licensed components into the kernel
+#device dtrace
+
+# DTrace modules
+#device dtrace_lockstat
+#device dtrace_profile
+#device dtrace_sdt
+#device dtrace_fbt
+#device dtrace_systrace
+#device dtrace_prototype
+#device dtnfscl
+#device dtmalloc
+
+# Alternatively include all the DTrace modules
+#device dtraceall
#####################################################################
diff --git a/sys/powerpc/include/vmparam.h b/sys/powerpc/include/vmparam.h
index c79a7c54f2ed..5b808abc1fee 100644
--- a/sys/powerpc/include/vmparam.h
+++ b/sys/powerpc/include/vmparam.h
@@ -136,13 +136,12 @@ struct pmap_physseg {
#endif
/*
- * Create three free page pools: VM_FREEPOOL_DEFAULT is the default pool
+ * Create two free page pools: VM_FREEPOOL_DEFAULT is the default pool
* from which physical pages are allocated and VM_FREEPOOL_DIRECT is
* the pool from which physical pages for small UMA objects are
* allocated.
*/
-#define VM_NFREEPOOL 3
-#define VM_FREEPOOL_CACHE 2
+#define VM_NFREEPOOL 2
#define VM_FREEPOOL_DEFAULT 0
#define VM_FREEPOOL_DIRECT 1
diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c
index ea00306787ce..bdcd9babb8c5 100644
--- a/sys/powerpc/powerpc/elf32_machdep.c
+++ b/sys/powerpc/powerpc/elf32_machdep.c
@@ -108,6 +108,7 @@ struct sysentvec elf32_freebsd_sysvec = {
.sv_shared_page_base = FREEBSD32_SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
INIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec);
diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c
index 0b15ca3dea86..47fbbff2febd 100644
--- a/sys/powerpc/powerpc/elf64_machdep.c
+++ b/sys/powerpc/powerpc/elf64_machdep.c
@@ -84,6 +84,7 @@ struct sysentvec elf64_freebsd_sysvec = {
.sv_shared_page_base = SHAREDPAGE,
.sv_shared_page_len = PAGE_SIZE,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c
index 67ce4bc60c6e..0019faaa93bc 100644
--- a/sys/powerpc/powerpc/exec_machdep.c
+++ b/sys/powerpc/powerpc/exec_machdep.c
@@ -226,12 +226,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
}
/*
- * Translate the signal if appropriate (Linux emu ?)
- */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
- /*
* Save the floating-point state, if necessary, then copy it.
*/
/* XXX */
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index 0ceb17081445..bfbd94d2166e 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -196,8 +196,8 @@ trap(struct trapframe *frame)
if (user) {
td->td_pticks = 0;
td->td_frame = frame;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
/* User Mode Traps */
switch (type) {
diff --git a/sys/sparc64/include/vmparam.h b/sys/sparc64/include/vmparam.h
index c2f30c3f2734..facec86790ee 100644
--- a/sys/sparc64/include/vmparam.h
+++ b/sys/sparc64/include/vmparam.h
@@ -75,13 +75,12 @@
#define VM_PHYSSEG_MAX 64
/*
- * Create three free page pools: VM_FREEPOOL_DEFAULT is the default pool
+ * Create two free page pools: VM_FREEPOOL_DEFAULT is the default pool
* from which physical pages are allocated and VM_FREEPOOL_DIRECT is
* the pool from which physical pages for small UMA objects are
* allocated.
*/
-#define VM_NFREEPOOL 3
-#define VM_FREEPOOL_CACHE 2
+#define VM_NFREEPOOL 2
#define VM_FREEPOOL_DEFAULT 0
#define VM_FREEPOOL_DIRECT 1
diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c
index 4d5571781d11..93045757e436 100644
--- a/sys/sparc64/sparc64/elf_machdep.c
+++ b/sys/sparc64/sparc64/elf_machdep.c
@@ -87,6 +87,7 @@ static struct sysentvec elf64_freebsd_sysvec = {
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
.sv_schedtail = NULL,
+ .sv_thread_detach = NULL,
};
static Elf64_Brandinfo freebsd_brand_info = {
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 67f7d643d984..a95bc637761f 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -654,10 +654,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
fp = (struct frame *)sfp - 1;
- /* Translate the signal if appropriate. */
- if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
- sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
/* Build the argument list for the signal handler. */
tf->tf_out[0] = sig;
tf->tf_out[2] = (register_t)&sfp->sf_uc;
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index b4f0e27fa6d2..e9917e529535 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -277,8 +277,8 @@ trap(struct trapframe *tf)
td->td_pticks = 0;
td->td_frame = tf;
addr = tf->tf_tpc;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
+ if (td->td_cowgen != p->p_cowgen)
+ thread_cow_update(td);
switch (tf->tf_type) {
case T_DATA_MISS:
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 8b1f1736a17f..42d3a3fea5e8 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -612,7 +612,7 @@ void bus_data_generation_update(void);
#define BUS_PROBE_DEFAULT (-20) /* Base OS default driver */
#define BUS_PROBE_LOW_PRIORITY (-40) /* Older, less desirable drivers */
#define BUS_PROBE_GENERIC (-100) /* generic driver for dev */
-#define BUS_PROBE_HOOVER (-500) /* Generic dev for all devs on bus */
+#define BUS_PROBE_HOOVER (-1000000) /* Driver for any dev on bus */
#define BUS_PROBE_NOWILDCARD (-2000000000) /* No wildcard device matches */
/**
diff --git a/sys/sys/file.h b/sys/sys/file.h
index 153885123704..cb51c27f76b1 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -42,6 +42,7 @@
#include <sys/refcount.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
+#include <vm/vm.h>
struct filedesc;
struct stat;
@@ -66,6 +67,7 @@ struct socket;
#define DTYPE_PTS 10 /* pseudo teletype master device */
#define DTYPE_DEV 11 /* Device specific fd type */
#define DTYPE_PROCDESC 12 /* process descriptor */
+#define DTYPE_LINUXEFD 13 /* emulation eventfd type */
#ifdef _KERNEL
@@ -114,6 +116,9 @@ typedef int fo_seek_t(struct file *fp, off_t offset, int whence,
struct thread *td);
typedef int fo_fill_kinfo_t(struct file *fp, struct kinfo_file *kif,
struct filedesc *fdp);
+typedef int fo_mmap_t(struct file *fp, vm_map_t map, vm_offset_t *addr,
+ vm_size_t size, vm_prot_t prot, vm_prot_t cap_maxprot,
+ int flags, vm_ooffset_t foff, struct thread *td);
typedef int fo_flags_t;
struct fileops {
@@ -130,6 +135,7 @@ struct fileops {
fo_sendfile_t *fo_sendfile;
fo_seek_t *fo_seek;
fo_fill_kinfo_t *fo_fill_kinfo;
+ fo_mmap_t *fo_mmap;
fo_flags_t fo_flags; /* DFLAG_* below */
};
@@ -390,6 +396,18 @@ fo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
return ((*fp->f_ops->fo_fill_kinfo)(fp, kif, fdp));
}
+static __inline int
+fo_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
+ vm_prot_t prot, vm_prot_t cap_maxprot, int flags, vm_ooffset_t foff,
+ struct thread *td)
+{
+
+ if (fp->f_ops->fo_mmap == NULL)
+ return (ENODEV);
+ return ((*fp->f_ops->fo_mmap)(fp, map, addr, size, prot, cap_maxprot,
+ flags, foff, td));
+}
+
#endif /* _KERNEL */
#endif /* !SYS_FILE_H */
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index eca30ffd9847..3fe61c883cd7 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -83,8 +83,8 @@ struct filedesc {
int fd_lastfile; /* high-water mark of fd_ofiles */
int fd_freefile; /* approx. next free file */
u_short fd_cmask; /* mask for file creation */
- u_short fd_refcnt; /* thread reference count */
- u_short fd_holdcnt; /* hold count on structure + mutex */
+ int fd_refcnt; /* thread reference count */
+ int fd_holdcnt; /* hold count on structure + mutex */
struct sx fd_sx; /* protects members of this struct */
struct kqlist fd_kqlist; /* list of kqueues on this filedesc */
int fd_holdleaderscount; /* block fdfree() for shared close() */
diff --git a/sys/sys/ktr_class.h b/sys/sys/ktr_class.h
index bdd7c1a1142f..6635cdc8f1cc 100644
--- a/sys/sys/ktr_class.h
+++ b/sys/sys/ktr_class.h
@@ -71,7 +71,8 @@
#define KTR_INET6 0x10000000 /* IPv6 stack */
#define KTR_SCHED 0x20000000 /* Machine parsed sched info. */
#define KTR_BUF 0x40000000 /* Buffer cache */
-#define KTR_ALL 0x7fffffff
+#define KTR_PTRACE 0x80000000 /* Process debugging. */
+#define KTR_ALL 0xffffffff
/* KTR trace classes to compile in */
#ifdef KTR
diff --git a/sys/sys/lockstat.h b/sys/sys/lockstat.h
index ed9cffa92b62..2a7853fb95bf 100644
--- a/sys/sys/lockstat.h
+++ b/sys/sys/lockstat.h
@@ -198,6 +198,9 @@ extern uint64_t lockstat_nsecs(void);
(*lockstat_probe_func)(id, (uintptr_t)(lp), 0, 0, 0, 0); \
} while (0)
+#define LOCKSTAT_WRITER 0
+#define LOCKSTAT_READER 1
+
#else /* !KDTRACE_HOOKS */
#define LOCKSTAT_RECORD(probe, lp, arg1)
diff --git a/sys/sys/mman.h b/sys/sys/mman.h
index 53b656ceb28d..19d992e83361 100644
--- a/sys/sys/mman.h
+++ b/sys/sys/mman.h
@@ -230,8 +230,6 @@ struct shmfd {
#endif
#ifdef _KERNEL
-int shm_mmap(struct shmfd *shmfd, vm_size_t objsize, vm_ooffset_t foff,
- vm_object_t *obj);
int shm_map(struct file *fp, size_t size, off_t offset, void **memp);
int shm_unmap(struct file *fp, void *mem, size_t size);
diff --git a/sys/sys/nlist_aout.h b/sys/sys/nlist_aout.h
index fc7a3c781c57..cb3dd8591252 100644
--- a/sys/sys/nlist_aout.h
+++ b/sys/sys/nlist_aout.h
@@ -56,8 +56,6 @@ struct nlist {
} n_un;
#else
const char *n_name; /* symbol name (in memory) */
- int : 8 * (sizeof(long) > sizeof(char *) ?
- sizeof(long) - sizeof(char *) : sizeof(char *) - sizeof(long));
#endif
unsigned char n_type; /* type defines */
char n_other; /* ".type" and binding information */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index cbc290129516..a146da86a42f 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1100073 /* Master, propagated to newvers */
+#define __FreeBSD_version 1100077 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h
index f4d46b2e950f..e0e7fcb4cf15 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -105,7 +105,12 @@
__PMC_CPU(PPC_MPC85XX, 0x340, "Freescale PowerPC MPC85XX") \
__PMC_CPU(PPC_970, 0x380, "IBM PowerPC 970") \
__PMC_CPU(GENERIC, 0x400, "Generic") \
- __PMC_CPU(ARMV7, 0x500, "ARMv7") \
+ __PMC_CPU(ARMV7_CORTEX_A5, 0x500, "ARMv7 Cortex A5") \
+ __PMC_CPU(ARMV7_CORTEX_A7, 0x501, "ARMv7 Cortex A7") \
+ __PMC_CPU(ARMV7_CORTEX_A8, 0x502, "ARMv7 Cortex A8") \
+ __PMC_CPU(ARMV7_CORTEX_A9, 0x503, "ARMv7 Cortex A9") \
+ __PMC_CPU(ARMV7_CORTEX_A15, 0x504, "ARMv7 Cortex A15") \
+ __PMC_CPU(ARMV7_CORTEX_A17, 0x505, "ARMv7 Cortex A17") \
__PMC_CPU(ARMV8_CORTEX_A53, 0x600, "ARMv8 Cortex A53") \
__PMC_CPU(ARMV8_CORTEX_A57, 0x601, "ARMv8 Cortex A57")
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 6b1a2f07621c..e6c83b43940b 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -246,6 +246,7 @@ struct thread {
int td_intr_nesting_level; /* (k) Interrupt recursion. */
int td_pinned; /* (k) Temporary cpu pin count. */
struct ucred *td_ucred; /* (k) Reference to credentials. */
+ struct plimit *td_limit; /* (k) Resource limits. */
u_int td_estcpu; /* (t) estimated cpu utilization */
int td_slptick; /* (t) Time at sleep. */
int td_blktick; /* (t) Time spent blocked. */
@@ -277,6 +278,7 @@ struct thread {
u_int td_vp_reserv; /* (k) Count of reserved vnodes. */
int td_no_sleeping; /* (k) Sleeping disabled count. */
int td_dom_rr_idx; /* (k) RR Numa domain selection. */
+ void *td_su; /* (k) FFS SU private */
#define td_endzero td_sigmask
/* Copied during fork1() or create_thread(). */
@@ -307,6 +309,7 @@ struct thread {
off_t tdu_off;
} td_uretoff; /* (k) Syscall aux returns. */
#define td_retval td_uretoff.tdu_retval
+ u_int td_cowgen; /* (k) Generation of COW pointers. */
struct callout td_slpcallout; /* (h) Callout for sleep. */
struct trapframe *td_frame; /* (k) */
struct vm_object *td_kstack_obj;/* (a) Kstack object. */
@@ -325,6 +328,7 @@ struct thread {
struct proc *td_rfppwait_p; /* (k) The vforked child */
struct vm_page **td_ma; /* (k) uio pages held */
int td_ma_cnt; /* (k) size of *td_ma */
+ void *td_emuldata; /* Emulator state data */
};
struct mtx *thread_lock_block(struct thread *);
@@ -496,7 +500,7 @@ struct proc {
struct filedesc *p_fd; /* (b) Open files. */
struct filedesc_to_leader *p_fdtol; /* (b) Tracking node */
struct pstats *p_stats; /* (b) Accounting/statistics (CPU). */
- struct plimit *p_limit; /* (c) Process limits. */
+ struct plimit *p_limit; /* (c) Resource limits. */
struct callout p_limco; /* (c) Limit callout handle */
struct sigacts *p_sigacts; /* (x) Signal actions, state (CPU). */
@@ -531,6 +535,7 @@ struct proc {
pid_t p_oppid; /* (c + e) Save ppid in ptrace. XXX */
struct vmspace *p_vmspace; /* (b) Address space. */
u_int p_swtick; /* (c) Tick when swapped in or out. */
+ u_int p_cowgen; /* (c) Generation of COW pointers. */
struct itimerval p_realtimer; /* (c) Alarm timer. */
struct rusage p_ru; /* (a) Exit information. */
struct rusage_ext p_rux; /* (cu) Internal resource usage. */
@@ -676,6 +681,7 @@ struct proc {
#define P2_INHERIT_PROTECTED 0x00000001 /* New children get P_PROTECTED. */
#define P2_NOTRACE 0x00000002 /* No ptrace(2) attach or coredumps. */
#define P2_NOTRACE_EXEC 0x00000004 /* Keep P2_NOPTRACE on exec(2). */
+#define P2_AST_SU 0x00000008 /* Handles SU ast for kthreads. */
/* Flags protected by proctree_lock, kept in p_treeflags. */
#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */
@@ -830,6 +836,11 @@ extern pid_t pid_max;
KASSERT((p)->p_lock == 0, ("process held")); \
} while (0)
+#define PROC_UPDATE_COW(p) do { \
+ PROC_LOCK_ASSERT((p), MA_OWNED); \
+ (p)->p_cowgen++; \
+} while (0)
+
/* Check whether a thread is safe to be swapped out. */
#define thread_safetoswapout(td) ((td)->td_flags & TDF_CANSWAP)
@@ -974,6 +985,10 @@ void cpu_thread_swapin(struct thread *);
void cpu_thread_swapout(struct thread *);
struct thread *thread_alloc(int pages);
int thread_alloc_stack(struct thread *, int pages);
+void thread_cow_get_proc(struct thread *newtd, struct proc *p);
+void thread_cow_get(struct thread *newtd, struct thread *td);
+void thread_cow_free(struct thread *td);
+void thread_cow_update(struct thread *td);
void thread_exit(void) __dead2;
void thread_free(struct thread *td);
void thread_link(struct thread *td, struct proc *p);
diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h
index a07fdf8d2427..b4c707d5e130 100644
--- a/sys/sys/resourcevar.h
+++ b/sys/sys/resourcevar.h
@@ -130,13 +130,16 @@ int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
struct plimit
*lim_alloc(void);
void lim_copy(struct plimit *dst, struct plimit *src);
-rlim_t lim_cur(struct proc *p, int which);
+rlim_t lim_cur(struct thread *td, int which);
+rlim_t lim_cur_proc(struct proc *p, int which);
void lim_fork(struct proc *p1, struct proc *p2);
void lim_free(struct plimit *limp);
struct plimit
*lim_hold(struct plimit *limp);
-rlim_t lim_max(struct proc *p, int which);
-void lim_rlimit(struct proc *p, int which, struct rlimit *rlp);
+rlim_t lim_max(struct thread *td, int which);
+rlim_t lim_max_proc(struct proc *p, int which);
+void lim_rlimit(struct thread *td, int which, struct rlimit *rlp);
+void lim_rlimit_proc(struct proc *p, int which, struct rlimit *rlp);
void ruadd(struct rusage *ru, struct rusage_ext *rux, struct rusage *ru2,
struct rusage_ext *rux2);
void rucollect(struct rusage *ru, struct rusage *ru2);
@@ -156,5 +159,7 @@ void ui_racct_foreach(void (*callback)(struct racct *racct,
void *arg2, void *arg3), void *arg2, void *arg3);
#endif
+void lim_update_thread(struct thread *td);
+
#endif /* _KERNEL */
#endif /* !_SYS_RESOURCEVAR_H_ */
diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h
index 40de36e38d3a..580cbd2ed5cb 100644
--- a/sys/sys/sbuf.h
+++ b/sys/sys/sbuf.h
@@ -58,6 +58,14 @@ struct sbuf {
ssize_t s_sect_len; /* current length of section */
};
+#ifndef HD_COLUMN_MASK
+#define HD_COLUMN_MASK 0xff
+#define HD_DELIM_MASK 0xff00
+#define HD_OMIT_COUNT (1 << 16)
+#define HD_OMIT_HEX (1 << 17)
+#define HD_OMIT_CHARS (1 << 18)
+#endif /* HD_COLUMN_MASK */
+
__BEGIN_DECLS
/*
* API functions
@@ -89,6 +97,8 @@ int sbuf_done(const struct sbuf *);
void sbuf_delete(struct sbuf *);
void sbuf_start_section(struct sbuf *, ssize_t *);
ssize_t sbuf_end_section(struct sbuf *, ssize_t, size_t, int);
+void sbuf_hexdump(struct sbuf *, const void *, int, const char *,
+ int);
#ifdef _KERNEL
struct uio;
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index 8624ad2e3b13..73ebf5f1c942 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -96,7 +96,7 @@
#define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */
#define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set linklevel addr */
-#define SIOCGI2C _IOWR('i', 61, struct ifstat) /* get I2C data */
+#define SIOCGI2C _IOWR('i', 61, struct ifreq) /* get I2C data */
#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif addres */
#define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 8d8c1736bcac..4ff111ee8a3e 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -55,6 +55,7 @@ struct sendfile_args;
struct sockaddr;
struct stat;
struct thr_param;
+struct sched_param;
struct __wrusage;
int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg,
@@ -120,6 +121,10 @@ int kern_jail_get(struct thread *td, struct uio *options, int flags);
int kern_jail_set(struct thread *td, struct uio *options, int flags);
int kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout);
+int kern_kevent_fp(struct thread *td, struct file *fp, int nchanges,
+ int nevents, struct kevent_copyops *k_ops,
+ const struct timespec *timeout);
+int kern_kqueue(struct thread *td, int flags);
int kern_kldload(struct thread *td, const char *file, int *fileid);
int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat);
int kern_kldunload(struct thread *td, int fileid, int flags);
@@ -169,8 +174,18 @@ int kern_renameat(struct thread *td, int oldfd, char *old, int newfd,
char *new, enum uio_seg pathseg);
int kern_rmdirat(struct thread *td, int fd, char *path,
enum uio_seg pathseg);
+int kern_sched_getparam(struct thread *td, struct thread *targettd,
+ struct sched_param *param);
+int kern_sched_getscheduler(struct thread *td, struct thread *targettd,
+ int *policy);
+int kern_sched_setparam(struct thread *td, struct thread *targettd,
+ struct sched_param *param);
+int kern_sched_setscheduler(struct thread *td, struct thread *targettd,
+ int policy, struct sched_param *param);
int kern_sched_rr_get_interval(struct thread *td, pid_t pid,
struct timespec *ts);
+int kern_sched_rr_get_interval_td(struct thread *td, struct thread *targettd,
+ struct timespec *ts);
int kern_semctl(struct thread *td, int semid, int semnum, int cmd,
union semun *arg, register_t *rval);
int kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou,
@@ -214,6 +229,8 @@ int kern_ktimer_settime(struct thread *td, int timer_id, int flags,
int kern_ktimer_gettime(struct thread *td, int timer_id,
struct itimerspec *val);
int kern_ktimer_getoverrun(struct thread *td, int timer_id);
+int kern_thr_alloc(struct proc *, int pages, struct thread **);
+int kern_thr_exit(struct thread *td);
int kern_thr_new(struct thread *td, struct thr_param *param);
int kern_thr_suspend(struct thread *td, struct timespec *tsp);
int kern_truncate(struct thread *td, char *path, enum uio_seg pathseg,
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
index bef27ceeb995..b1f61a9d06cc 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -136,6 +136,7 @@ struct sysentvec {
uint32_t sv_timekeep_gen;
void *sv_shared_page_obj;
void (*sv_schedtail)(struct thread *);
+ void (*sv_thread_detach)(struct thread *);
};
#define SV_ILP32 0x000100
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index acea565c0ab2..cb05a00008e7 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -431,4 +431,6 @@ void free_unr(struct unrhdr *uh, u_int item);
void intr_prof_stack_use(struct thread *td, struct trapframe *frame);
+extern void (*softdep_ast_cleanup)(void);
+
#endif /* !_SYS_SYSTM_H_ */
diff --git a/sys/sys/user.h b/sys/sys/user.h
index c3b3bc59b414..e831a37ce541 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -486,6 +486,27 @@ struct kinfo_vmentry {
};
/*
+ * The "vm.objects" sysctl provides a list of all VM objects in the system
+ * via an array of these entries.
+ */
+struct kinfo_vmobject {
+ int kvo_structsize; /* Variable size of record. */
+ int kvo_type; /* Object type: KVME_TYPE_*. */
+ uint64_t kvo_size; /* Object size in pages. */
+ uint64_t kvo_vn_fileid; /* inode number if vnode. */
+ uint32_t kvo_vn_fsid; /* dev_t of vnode location. */
+ int kvo_ref_count; /* Reference count. */
+ int kvo_shadow_count; /* Shadow count. */
+ int kvo_memattr; /* Memory attribute. */
+ uint64_t kvo_resident; /* Number of resident pages. */
+ uint64_t kvo_active; /* Number of active pages. */
+ uint64_t kvo_inactive; /* Number of inactive pages. */
+ uint64_t _kvo_qspare[8];
+ uint32_t _kvo_ispare[8];
+ char kvo_path[PATH_MAX]; /* Pathname, if any. */
+};
+
+/*
* The KERN_PROC_KSTACK sysctl allows a process to dump the kernel stacks of
* another process as a series of entries. Each stack is represented by a
* series of symbol names and offsets as generated by stack_sbuf_print(9).
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index d70aa579c1b1..36ef8af08e89 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -397,6 +397,7 @@ extern int vttoif_tab[];
#define V_WAIT 0x0001 /* vn_start_write: sleep for suspend */
#define V_NOWAIT 0x0002 /* vn_start_write: don't sleep for suspend */
#define V_XSLEEP 0x0004 /* vn_start_write: just return after sleep */
+#define V_MNTREF 0x0010 /* vn_start_write: mp is already ref-ed */
#define VR_START_WRITE 0x0001 /* vfs_write_resume: start write atomically */
#define VR_NO_SUSPCLR 0x0002 /* vfs_write_resume: do not clear suspension */
@@ -691,7 +692,7 @@ int vn_rdwr_inchunks(enum uio_rw rw, struct vnode *vp, void *base,
struct ucred *active_cred, struct ucred *file_cred, size_t *aresid,
struct thread *td);
int vn_rlimit_fsize(const struct vnode *vn, const struct uio *uio,
- const struct thread *td);
+ struct thread *td);
int vn_stat(struct vnode *vp, struct stat *sb, struct ucred *active_cred,
struct ucred *file_cred, struct thread *td);
int vn_start_write(struct vnode *vp, struct mount **mpp, int flags);
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index ab2bd413820c..4fee2655793f 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -900,6 +900,8 @@ static int pagedep_find(struct pagedep_hashhead *, ino_t, ufs_lbn_t,
struct pagedep **);
static void pause_timer(void *);
static int request_cleanup(struct mount *, int);
+static void schedule_cleanup(struct mount *);
+static void softdep_ast_cleanup_proc(void);
static int process_worklist_item(struct mount *, int, int);
static void process_removes(struct vnode *);
static void process_truncates(struct vnode *);
@@ -921,6 +923,8 @@ static int journal_unsuspend(struct ufsmount *ump);
static void softdep_prelink(struct vnode *, struct vnode *);
static void add_to_journal(struct worklist *);
static void remove_from_journal(struct worklist *);
+static bool softdep_excess_inodes(struct ufsmount *);
+static bool softdep_excess_dirrem(struct ufsmount *);
static void softdep_process_journal(struct mount *, struct worklist *, int);
static struct jremref *newjremref(struct dirrem *, struct inode *,
struct inode *ip, off_t, nlink_t);
@@ -2059,7 +2063,6 @@ retry_flush:
* allocates a new structure if an existing one is not found.
*/
#define DEPALLOC 0x0001 /* allocate structure if lookup fails */
-#define NODELAY 0x0002 /* cannot do background work */
/*
* Structures and routines associated with pagedep caching.
@@ -2209,12 +2212,10 @@ inodedep_lookup(mp, inum, flags, inodedeppp)
* responsible for more than our share of that usage and
* we are not in a rush, request some inodedep cleanup.
*/
- while (dep_current[D_INODEDEP] > max_softdeps &&
- (flags & NODELAY) == 0 &&
- ump->softdep_curdeps[D_INODEDEP] >
- max_softdeps / stat_flush_threads)
- request_cleanup(mp, FLUSH_INODES);
- FREE_LOCK(ump);
+ if (softdep_excess_inodes(ump))
+ schedule_cleanup(mp);
+ else
+ FREE_LOCK(ump);
inodedep = malloc(sizeof(struct inodedep),
M_INODEDEP, M_SOFTDEP_FLAGS);
workitem_alloc(&inodedep->id_list, D_INODEDEP, mp);
@@ -2412,6 +2413,7 @@ softdep_initialize()
bioops.io_complete = softdep_disk_write_complete;
bioops.io_deallocate = softdep_deallocate_dependencies;
bioops.io_countdeps = softdep_count_dependencies;
+ softdep_ast_cleanup = softdep_ast_cleanup_proc;
/* Initialize the callout with an mtx. */
callout_init_mtx(&softdep_callout, &lk, 0);
@@ -2430,6 +2432,7 @@ softdep_uninitialize()
bioops.io_complete = NULL;
bioops.io_deallocate = NULL;
bioops.io_countdeps = NULL;
+ softdep_ast_cleanup = NULL;
callout_drain(&softdep_callout);
}
@@ -4631,14 +4634,10 @@ inodedep_lookup_ip(ip)
struct inode *ip;
{
struct inodedep *inodedep;
- int dflags;
KASSERT(ip->i_nlink >= ip->i_effnlink,
("inodedep_lookup_ip: bad delta"));
- dflags = DEPALLOC;
- if (IS_SNAPSHOT(ip))
- dflags |= NODELAY;
- (void) inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, dflags,
+ (void) inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, DEPALLOC,
&inodedep);
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
KASSERT((inodedep->id_state & UNLINKED) == 0, ("inode unlinked"));
@@ -4692,12 +4691,10 @@ softdep_setup_dotdot_link(dp, ip)
struct inodedep *inodedep;
struct jaddref *jaddref;
struct vnode *dvp;
- struct vnode *vp;
KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
("softdep_setup_dotdot_link called on non-softdep filesystem"));
dvp = ITOV(dp);
- vp = ITOV(ip);
jaddref = NULL;
/*
* We don't set MKDIR_PARENT as this is not tied to a mkdir and
@@ -5038,7 +5035,7 @@ softdep_setup_inomapdep(bp, ip, newinum, mode)
M_BMSAFEMAP, M_SOFTDEP_FLAGS);
workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
ACQUIRE_LOCK(ip->i_ump);
- if ((inodedep_lookup(mp, newinum, DEPALLOC | NODELAY, &inodedep)))
+ if ((inodedep_lookup(mp, newinum, DEPALLOC, &inodedep)))
panic("softdep_setup_inomapdep: dependency %p for new"
"inode already exists", inodedep);
bmsafemap = bmsafemap_lookup(mp, bp, ino_to_cg(fs, newinum), bmsafemap);
@@ -5335,7 +5332,7 @@ softdep_setup_allocdirect(ip, off, newblkno, oldblkno, newsize, oldsize, bp)
if (freefrag && freefrag->ff_jdep != NULL &&
freefrag->ff_jdep->wk_type == D_JFREEFRAG)
add_to_journal(freefrag->ff_jdep);
- inodedep_lookup(mp, ip->i_number, DEPALLOC | NODELAY, &inodedep);
+ inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
adp->ad_inodedep = inodedep;
WORKLIST_INSERT(&bp->b_dep, &newblk->nb_list);
@@ -5693,7 +5690,7 @@ softdep_setup_allocext(ip, off, newblkno, oldblkno, newsize, oldsize, bp)
if (freefrag && freefrag->ff_jdep != NULL &&
freefrag->ff_jdep->wk_type == D_JFREEFRAG)
add_to_journal(freefrag->ff_jdep);
- inodedep_lookup(mp, ip->i_number, DEPALLOC | NODELAY, &inodedep);
+ inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
adp->ad_inodedep = inodedep;
WORKLIST_INSERT(&bp->b_dep, &newblk->nb_list);
@@ -5818,7 +5815,6 @@ softdep_setup_allocindir_page(ip, lbn, bp, ptrno, newblkno, oldblkno, nbp)
struct allocindir *aip;
struct pagedep *pagedep;
struct mount *mp;
- int dflags;
mp = UFSTOVFS(ip->i_ump);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
@@ -5831,10 +5827,7 @@ softdep_setup_allocindir_page(ip, lbn, bp, ptrno, newblkno, oldblkno, nbp)
"lbn %jd", ip->i_number, newblkno, oldblkno, lbn);
ASSERT_VOP_LOCKED(ITOV(ip), "softdep_setup_allocindir_page");
aip = newallocindir(ip, ptrno, newblkno, oldblkno, lbn);
- dflags = DEPALLOC;
- if (IS_SNAPSHOT(ip))
- dflags |= NODELAY;
- (void) inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
+ (void) inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
/*
* If we are allocating a directory page, then we must
* allocate an associated pagedep to track additions and
@@ -5864,7 +5857,6 @@ softdep_setup_allocindir_meta(nbp, ip, bp, ptrno, newblkno)
struct inodedep *inodedep;
struct allocindir *aip;
ufs_lbn_t lbn;
- int dflags;
KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
("softdep_setup_allocindir_meta called on non-softdep filesystem"));
@@ -5874,10 +5866,8 @@ softdep_setup_allocindir_meta(nbp, ip, bp, ptrno, newblkno)
lbn = nbp->b_lblkno;
ASSERT_VOP_LOCKED(ITOV(ip), "softdep_setup_allocindir_meta");
aip = newallocindir(ip, ptrno, newblkno, 0, lbn);
- dflags = DEPALLOC;
- if (IS_SNAPSHOT(ip))
- dflags |= NODELAY;
- inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, dflags, &inodedep);
+ inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, DEPALLOC,
+ &inodedep);
WORKLIST_INSERT(&nbp->b_dep, &aip->ai_block.nb_list);
if (setup_allocindir_phase2(bp, ip, inodedep, aip, lbn))
panic("softdep_setup_allocindir_meta: Block already existed");
@@ -6490,7 +6480,7 @@ softdep_journal_freeblocks(ip, cred, length, flags)
struct mount *mp;
ufs2_daddr_t extblocks, datablocks;
ufs_lbn_t tmpval, lbn, lastlbn;
- int frags, lastoff, iboff, allocblock, needj, dflags, error, i;
+ int frags, lastoff, iboff, allocblock, needj, error, i;
fs = ip->i_fs;
ump = ip->i_ump;
@@ -6511,10 +6501,7 @@ softdep_journal_freeblocks(ip, cred, length, flags)
* we don't need to journal the block frees. The canceled journals
* for the allocations will suffice.
*/
- dflags = DEPALLOC;
- if (IS_SNAPSHOT(ip))
- dflags |= NODELAY;
- inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
+ inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
if ((inodedep->id_state & (UNLINKED | DEPCOMPLETE)) == UNLINKED &&
length == 0)
needj = 0;
@@ -6644,7 +6631,7 @@ softdep_journal_freeblocks(ip, cred, length, flags)
*((struct ufs2_dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2;
ACQUIRE_LOCK(ump);
- (void) inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
+ (void) inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
if ((inodedep->id_state & IOSTARTED) != 0)
panic("softdep_setup_freeblocks: inode busy");
/*
@@ -6737,7 +6724,7 @@ softdep_journal_freeblocks(ip, cred, length, flags)
}
ACQUIRE_LOCK(ump);
- inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
+ inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
TAILQ_INSERT_TAIL(&inodedep->id_freeblklst, freeblks, fb_next);
freeblks->fb_state |= DEPCOMPLETE | ONDEPLIST;
/*
@@ -6828,7 +6815,7 @@ softdep_setup_freeblocks(ip, length, flags)
struct fs *fs;
ufs2_daddr_t extblocks, datablocks;
struct mount *mp;
- int i, delay, error, dflags;
+ int i, delay, error;
ufs_lbn_t tmpval;
ufs_lbn_t lbn;
@@ -6897,10 +6884,7 @@ softdep_setup_freeblocks(ip, length, flags)
* Find and eliminate any inode dependencies.
*/
ACQUIRE_LOCK(ump);
- dflags = DEPALLOC;
- if (IS_SNAPSHOT(ip))
- dflags |= NODELAY;
- (void) inodedep_lookup(mp, ip->i_number, dflags, &inodedep);
+ (void) inodedep_lookup(mp, ip->i_number, DEPALLOC, &inodedep);
if ((inodedep->id_state & IOSTARTED) != 0)
panic("softdep_setup_freeblocks: inode busy");
/*
@@ -7066,7 +7050,6 @@ trunc_dependencies(ip, freeblks, lastlbn, lastoff, flags)
struct bufobj *bo;
struct vnode *vp;
struct buf *bp;
- struct fs *fs;
int blkoff;
/*
@@ -7075,7 +7058,6 @@ trunc_dependencies(ip, freeblks, lastlbn, lastoff, flags)
* Once they are all there, walk the list and get rid of
* any dependencies.
*/
- fs = ip->i_fs;
vp = ITOV(ip);
bo = &vp->v_bufobj;
BO_LOCK(bo);
@@ -7226,7 +7208,6 @@ deallocate_dependencies(bp, freeblks, off)
{
struct indirdep *indirdep;
struct pagedep *pagedep;
- struct allocdirect *adp;
struct worklist *wk, *wkn;
struct ufsmount *ump;
@@ -7273,7 +7254,6 @@ deallocate_dependencies(bp, freeblks, off)
break;
case D_ALLOCDIRECT:
- adp = WK_ALLOCDIRECT(wk);
if (off != 0)
continue;
/* FALLTHROUGH */
@@ -8506,7 +8486,7 @@ softdep_setup_directory_add(bp, dp, diroffset, newinum, newdirbp, isnewblk)
dap->da_pagedep = pagedep;
LIST_INSERT_HEAD(&pagedep->pd_diraddhd[DIRADDHASH(offset)], dap,
da_pdlist);
- inodedep_lookup(mp, newinum, DEPALLOC | NODELAY, &inodedep);
+ inodedep_lookup(mp, newinum, DEPALLOC, &inodedep);
/*
* If we're journaling, link the diradd into the jaddref so it
* may be completed after the journal entry is written. Otherwise,
@@ -9126,13 +9106,12 @@ newdirrem(bp, dp, ip, isrmdir, prevdirremp)
* the number of freefile and freeblks structures.
*/
ACQUIRE_LOCK(ip->i_ump);
- while (!IS_SNAPSHOT(ip) && dep_current[D_DIRREM] > max_softdeps / 2 &&
- ip->i_ump->softdep_curdeps[D_DIRREM] >
- (max_softdeps / 2) / stat_flush_threads)
- (void) request_cleanup(ITOV(dp)->v_mount, FLUSH_BLOCKS);
- FREE_LOCK(ip->i_ump);
- dirrem = malloc(sizeof(struct dirrem),
- M_DIRREM, M_SOFTDEP_FLAGS|M_ZERO);
+ if (!IS_SNAPSHOT(ip) && softdep_excess_dirrem(ip->i_ump))
+ schedule_cleanup(ITOV(dp)->v_mount);
+ else
+ FREE_LOCK(ip->i_ump);
+ dirrem = malloc(sizeof(struct dirrem), M_DIRREM, M_SOFTDEP_FLAGS |
+ M_ZERO);
workitem_alloc(&dirrem->dm_list, D_DIRREM, dvp->v_mount);
LIST_INIT(&dirrem->dm_jremrefhd);
LIST_INIT(&dirrem->dm_jwork);
@@ -9368,7 +9347,7 @@ softdep_setup_directory_change(bp, dp, ip, newinum, isrmdir)
* inode is not yet written. If it is written, do the post-inode
* write processing to put it on the id_pendinghd list.
*/
- inodedep_lookup(mp, newinum, DEPALLOC | NODELAY, &inodedep);
+ inodedep_lookup(mp, newinum, DEPALLOC, &inodedep);
if (MOUNTEDSUJ(mp)) {
jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
inoreflst);
@@ -9410,15 +9389,12 @@ softdep_change_linkcnt(ip)
struct inode *ip; /* the inode with the increased link count */
{
struct inodedep *inodedep;
- int dflags;
KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
("softdep_change_linkcnt called on non-softdep filesystem"));
ACQUIRE_LOCK(ip->i_ump);
- dflags = DEPALLOC;
- if (IS_SNAPSHOT(ip))
- dflags |= NODELAY;
- inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, dflags, &inodedep);
+ inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, DEPALLOC,
+ &inodedep);
if (ip->i_nlink < ip->i_effnlink)
panic("softdep_change_linkcnt: bad delta");
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
@@ -9511,12 +9487,10 @@ handle_written_sbdep(sbdep, bp)
struct buf *bp;
{
struct inodedep *inodedep;
- struct mount *mp;
struct fs *fs;
LOCK_OWNED(sbdep->sb_ump);
fs = sbdep->sb_fs;
- mp = UFSTOVFS(sbdep->sb_ump);
/*
* If the superblock doesn't match the in-memory list start over.
*/
@@ -13269,6 +13243,92 @@ retry:
return (1);
}
+static bool
+softdep_excess_inodes(struct ufsmount *ump)
+{
+
+ return (dep_current[D_INODEDEP] > max_softdeps &&
+ ump->softdep_curdeps[D_INODEDEP] > max_softdeps /
+ stat_flush_threads);
+}
+
+static bool
+softdep_excess_dirrem(struct ufsmount *ump)
+{
+
+ return (dep_current[D_DIRREM] > max_softdeps / 2 &&
+ ump->softdep_curdeps[D_DIRREM] > (max_softdeps / 2) /
+ stat_flush_threads);
+}
+
+static void
+schedule_cleanup(struct mount *mp)
+{
+ struct ufsmount *ump;
+ struct thread *td;
+
+ ump = VFSTOUFS(mp);
+ LOCK_OWNED(ump);
+ FREE_LOCK(ump);
+ td = curthread;
+ if ((td->td_pflags & TDP_KTHREAD) != 0 &&
+ (td->td_proc->p_flag2 & P2_AST_SU) == 0) {
+ /*
+ * No ast is delivered to kernel threads, so nobody
+ * would deref the mp. Some kernel threads
+ * explicitely check for AST, e.g. NFS daemon does
+ * this in the serving loop.
+ */
+ return;
+ }
+ if (td->td_su != NULL)
+ vfs_rel(td->td_su);
+ vfs_ref(mp);
+ td->td_su = mp;
+ thread_lock(td);
+ td->td_flags |= TDF_ASTPENDING;
+ thread_unlock(td);
+}
+
+static void
+softdep_ast_cleanup_proc(void)
+{
+ struct thread *td;
+ struct mount *mp;
+ struct ufsmount *ump;
+ int error;
+ bool req;
+
+ td = curthread;
+ mp = td->td_su;
+ if (mp == NULL)
+ return;
+ td->td_su = NULL;
+ error = vfs_busy(mp, MBF_NOWAIT);
+ vfs_rel(mp);
+ if (error != 0)
+ return;
+ if (ffs_own_mount(mp) && MOUNTEDSOFTDEP(mp)) {
+ ump = VFSTOUFS(mp);
+ for (;;) {
+ req = false;
+ ACQUIRE_LOCK(ump);
+ if (softdep_excess_inodes(ump)) {
+ req = true;
+ request_cleanup(mp, FLUSH_INODES);
+ }
+ if (softdep_excess_dirrem(ump)) {
+ req = true;
+ request_cleanup(mp, FLUSH_BLOCKS);
+ }
+ FREE_LOCK(ump);
+ if ((td->td_pflags & TDP_KTHREAD) != 0 || !req)
+ break;
+ }
+ }
+ vfs_unbusy(mp);
+}
+
/*
* If memory utilization has gotten too high, deliberately slow things
* down and speed up the I/O processing.
@@ -13355,7 +13415,8 @@ request_cleanup(mp, resource)
callout_reset(&softdep_callout, tickdelay > 2 ? tickdelay : 2,
pause_timer, 0);
- msleep((caddr_t)&proc_waiting, &lk, PPAUSE, "softupdate", 0);
+ if ((td->td_pflags & TDP_KTHREAD) == 0)
+ msleep((caddr_t)&proc_waiting, &lk, PPAUSE, "softupdate", 0);
proc_waiting -= 1;
FREE_GBLLOCK(&lk);
ACQUIRE_LOCK(ump);
diff --git a/sys/ufs/ffs/ffs_suspend.c b/sys/ufs/ffs/ffs_suspend.c
index b50fadcf3fa1..450282ceb179 100644
--- a/sys/ufs/ffs/ffs_suspend.c
+++ b/sys/ufs/ffs/ffs_suspend.c
@@ -177,7 +177,6 @@ out:
static int
ffs_susp_suspend(struct mount *mp)
{
- struct fs *fs;
struct ufsmount *ump;
int error;
@@ -189,7 +188,6 @@ ffs_susp_suspend(struct mount *mp)
return (EBUSY);
ump = VFSTOUFS(mp);
- fs = ump->um_fs;
/*
* Make sure the calling thread is permitted to access the mounted
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 2a368bd980fb..ce43bcd8a6ab 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1486,7 +1486,7 @@ ffs_sync(mp, waitfor)
struct inode *ip;
struct ufsmount *ump = VFSTOUFS(mp);
struct fs *fs;
- int error, count, wait, lockreq, allerror = 0;
+ int error, count, lockreq, allerror = 0;
int suspend;
int suspended;
int secondary_writes;
@@ -1495,7 +1495,6 @@ ffs_sync(mp, waitfor)
int softdep_accdeps;
struct bufobj *bo;
- wait = 0;
suspend = 0;
suspended = 0;
td = curthread;
@@ -1517,10 +1516,8 @@ ffs_sync(mp, waitfor)
suspend = 1;
waitfor = MNT_WAIT;
}
- if (waitfor == MNT_WAIT) {
- wait = 1;
+ if (waitfor == MNT_WAIT)
lockreq = LK_EXCLUSIVE;
- }
lockreq |= LK_INTERLOCK | LK_SLEEPFAIL;
loop:
/* Grab snapshot of secondary write counts */
@@ -2024,7 +2021,6 @@ static int
ffs_bufwrite(struct buf *bp)
{
struct buf *newbp;
- int oldflags;
CTR3(KTR_BUF, "bufwrite(%p) vp %p flags %X", bp, bp->b_vp, bp->b_flags);
if (bp->b_flags & B_INVAL) {
@@ -2032,8 +2028,6 @@ ffs_bufwrite(struct buf *bp)
return (0);
}
- oldflags = bp->b_flags;
-
if (!BUF_ISLOCKED(bp))
panic("bufwrite: buffer is not busy???");
/*
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 6b34a40256d2..618ed8e77d42 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -201,8 +201,8 @@ retry:
* bo_dirty list. Recheck and resync as needed.
*/
BO_LOCK(bo);
- if (vp->v_type == VREG && (bo->bo_numoutput > 0 ||
- bo->bo_dirty.bv_cnt > 0)) {
+ if ((vp->v_type == VREG || vp->v_type == VDIR) &&
+ (bo->bo_numoutput > 0 || bo->bo_dirty.bv_cnt > 0)) {
BO_UNLOCK(bo);
goto retry;
}
@@ -1366,11 +1366,6 @@ struct vop_openextattr_args {
};
*/
{
- struct inode *ip;
- struct fs *fs;
-
- ip = VTOI(ap->a_vp);
- fs = ip->i_fs;
if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
return (EOPNOTSUPP);
@@ -1394,11 +1389,6 @@ struct vop_closeextattr_args {
};
*/
{
- struct inode *ip;
- struct fs *fs;
-
- ip = VTOI(ap->a_vp);
- fs = ip->i_fs;
if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
return (EOPNOTSUPP);
@@ -1512,13 +1502,11 @@ vop_getextattr {
*/
{
struct inode *ip;
- struct fs *fs;
u_char *eae, *p;
unsigned easize;
int error, ealen;
ip = VTOI(ap->a_vp);
- fs = ip->i_fs;
if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
return (EOPNOTSUPP);
@@ -1567,14 +1555,12 @@ vop_listextattr {
*/
{
struct inode *ip;
- struct fs *fs;
u_char *eae, *p, *pe, *pn;
unsigned easize;
uint32_t ul;
int error, ealen;
ip = VTOI(ap->a_vp);
- fs = ip->i_fs;
if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
return (EOPNOTSUPP);
diff --git a/sys/ufs/ufs/ufs_bmap.c b/sys/ufs/ufs/ufs_bmap.c
index 22887c8ad9be..9819ef5eb8e5 100644
--- a/sys/ufs/ufs/ufs_bmap.c
+++ b/sys/ufs/ufs/ufs_bmap.c
@@ -114,7 +114,6 @@ ufs_bmaparray(vp, bn, bnp, nbp, runp, runb)
struct buf *bp;
struct ufsmount *ump;
struct mount *mp;
- struct vnode *devvp;
struct indir a[NIADDR+1], *ap;
ufs2_daddr_t daddr;
ufs_lbn_t metalbn;
@@ -125,7 +124,6 @@ ufs_bmaparray(vp, bn, bnp, nbp, runp, runb)
ip = VTOI(vp);
mp = vp->v_mount;
ump = VFSTOUFS(mp);
- devvp = ump->um_devvp;
if (runp) {
maxrun = mp->mnt_iosize_max / mp->mnt_stat.f_iosize - 1;
diff --git a/sys/ufs/ufs/ufs_dirhash.c b/sys/ufs/ufs/ufs_dirhash.c
index 39f29d09b1fb..766fe54b8997 100644
--- a/sys/ufs/ufs/ufs_dirhash.c
+++ b/sys/ufs/ufs/ufs_dirhash.c
@@ -190,9 +190,7 @@ ufsdirhash_create(struct inode *ip)
struct dirhash *ndh;
struct dirhash *dh;
struct vnode *vp;
- int error;
- error = 0;
ndh = dh = NULL;
vp = ip->i_vnode;
for (;;) {
@@ -274,11 +272,9 @@ static struct dirhash *
ufsdirhash_acquire(struct inode *ip)
{
struct dirhash *dh;
- struct vnode *vp;
ASSERT_VOP_ELOCKED(ip->i_vnode, __FUNCTION__);
- vp = ip->i_vnode;
dh = ip->i_dirhash;
if (dh == NULL)
return (NULL);
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 30054910c07a..5ade2bc452e6 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -224,16 +224,14 @@ swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred)
mtx_unlock(&sw_dev_mtx);
if (res) {
- PROC_LOCK(curproc);
UIDINFO_VMSIZE_LOCK(uip);
if ((overcommit & SWAP_RESERVE_RLIMIT_ON) != 0 &&
- uip->ui_vmsize + incr > lim_cur(curproc, RLIMIT_SWAP) &&
+ uip->ui_vmsize + incr > lim_cur(curthread, RLIMIT_SWAP) &&
priv_check(curthread, PRIV_VM_SWAP_NORLIMIT))
res = 0;
else
uip->ui_vmsize += incr;
UIDINFO_VMSIZE_UNLOCK(uip);
- PROC_UNLOCK(curproc);
if (!res) {
mtx_lock(&sw_dev_mtx);
swap_reserved -= incr;
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
index f639a22a5c43..922c3280302c 100644
--- a/sys/vm/vm_extern.h
+++ b/sys/vm/vm_extern.h
@@ -40,6 +40,8 @@ struct vnode;
struct vmem;
#ifdef _KERNEL
+struct cdev;
+struct cdevsw;
/* These operate on kernel virtual addresses only. */
vm_offset_t kva_alloc(vm_size_t);
@@ -81,10 +83,18 @@ int vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
int fault_flags, vm_page_t *m_hold);
int vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t addr, vm_size_t len,
vm_prot_t prot, vm_page_t *ma, int max_count);
-int vm_forkproc(struct thread *, struct proc *, struct thread *, struct vmspace *, int);
+int vm_forkproc(struct thread *, struct proc *, struct thread *,
+ struct vmspace *, int);
void vm_waitproc(struct proc *);
-int vm_mmap(vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, objtype_t, void *, vm_ooffset_t);
+int vm_mmap(vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int,
+ objtype_t, void *, vm_ooffset_t);
+int vm_mmap_object(vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t,
+ vm_prot_t, int, vm_object_t, vm_ooffset_t, boolean_t, struct thread *);
int vm_mmap_to_errno(int rv);
+int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
+ int *, struct cdev *, struct cdevsw *, vm_ooffset_t *, vm_object_t *);
+int vm_mmap_vnode(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, int *,
+ struct vnode *, vm_ooffset_t *, vm_object_t *, boolean_t *);
void vm_set_page_size(void);
void vm_sync_icache(vm_map_t, vm_offset_t, vm_size_t);
typedef int (*pmap_pinit_t)(struct pmap *pmap);
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 0c84d44c697e..7391465cc3d2 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -679,19 +679,12 @@ vnode_locked:
/*
* Found the page. Leave it busy while we play
* with it.
- */
-
- /*
- * Relookup in case pager changed page. Pager
+ *
+ * Pager could have changed the page. Pager
* is responsible for disposition of old page
* if moved.
*/
- fs.m = vm_page_lookup(fs.object, fs.pindex);
- if (!fs.m) {
- unlock_and_deallocate(&fs);
- goto RetryFault;
- }
-
+ fs.m = marray[reqpage];
hardfault++;
break; /* break to PAGE HAS BEEN FOUND */
}
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index c9ee890824a5..1ff17c29c3e6 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -230,7 +230,7 @@ vsunlock(void *addr, size_t len)
static vm_page_t
vm_imgact_hold_page(vm_object_t object, vm_ooffset_t offset)
{
- vm_page_t m, ma[1];
+ vm_page_t m;
vm_pindex_t pindex;
int rv;
@@ -238,11 +238,7 @@ vm_imgact_hold_page(vm_object_t object, vm_ooffset_t offset)
pindex = OFF_TO_IDX(offset);
m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL);
if (m->valid != VM_PAGE_BITS_ALL) {
- ma[0] = m;
- rv = vm_pager_get_pages(object, ma, 1, 0);
- m = vm_page_lookup(object, pindex);
- if (m == NULL)
- goto out;
+ rv = vm_pager_get_pages(object, &m, 1, 0);
if (rv != VM_PAGER_OK) {
vm_page_lock(m);
vm_page_free(m);
@@ -571,7 +567,7 @@ vm_thread_swapin(struct thread *td)
{
vm_object_t ksobj;
vm_page_t ma[KSTACK_MAX_PAGES];
- int i, j, k, pages, rv;
+ int i, j, pages, rv;
pages = td->td_kstack_pages;
ksobj = td->td_kstack_obj;
@@ -593,9 +589,12 @@ vm_thread_swapin(struct thread *td)
if (rv != VM_PAGER_OK)
panic("vm_thread_swapin: cannot get kstack for proc: %d",
td->td_proc->p_pid);
+ /*
+ * All pages in the array are in place, due to the
+ * pager is always the swap pager, which doesn't
+ * free or remove wired non-req pages from object.
+ */
vm_object_pip_wakeup(ksobj);
- for (k = i; k < j; k++)
- ma[k] = vm_page_lookup(ksobj, k);
vm_page_xunbusy(ma[i]);
} else if (vm_page_xbusied(ma[i]))
vm_page_xunbusy(ma[i]);
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index d4527b3b788e..fd16bf217b59 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -391,8 +391,7 @@ void
kmem_unback(vm_object_t object, vm_offset_t addr, vm_size_t size)
{
vm_page_t m;
- vm_offset_t offset;
- int i;
+ vm_offset_t i, offset;
KASSERT(object == kmem_object || object == kernel_object,
("kmem_unback: only supports kernel objects."));
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index bad999451ccb..12ebf5dfa1ce 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -3424,10 +3424,8 @@ vm_map_stack(vm_map_t map, vm_offset_t addrbos, vm_size_t max_ssize,
growsize = sgrowsiz;
init_ssize = (max_ssize < growsize) ? max_ssize : growsize;
vm_map_lock(map);
- PROC_LOCK(curproc);
- lmemlim = lim_cur(curproc, RLIMIT_MEMLOCK);
- vmemlim = lim_cur(curproc, RLIMIT_VMEM);
- PROC_UNLOCK(curproc);
+ lmemlim = lim_cur(curthread, RLIMIT_MEMLOCK);
+ vmemlim = lim_cur(curthread, RLIMIT_VMEM);
if (!old_mlock && map->flags & MAP_WIREFUTURE) {
if (ptoa(pmap_wired_count(map->pmap)) + init_ssize > lmemlim) {
rv = KERN_NO_SPACE;
@@ -3556,12 +3554,10 @@ vm_map_growstack(struct proc *p, vm_offset_t addr)
int error;
#endif
+ lmemlim = lim_cur(curthread, RLIMIT_MEMLOCK);
+ stacklim = lim_cur(curthread, RLIMIT_STACK);
+ vmemlim = lim_cur(curthread, RLIMIT_VMEM);
Retry:
- PROC_LOCK(p);
- lmemlim = lim_cur(p, RLIMIT_MEMLOCK);
- stacklim = lim_cur(p, RLIMIT_STACK);
- vmemlim = lim_cur(p, RLIMIT_VMEM);
- PROC_UNLOCK(p);
vm_map_lock_read(map);
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 1dd24792a85f..d331a9b22a27 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -100,13 +100,6 @@ SYSCTL_INT(_vm, OID_AUTO, old_mlock, CTLFLAG_RWTUN, &old_mlock, 0,
#define MAP_32BIT_MAX_ADDR ((vm_offset_t)1 << 31)
#endif
-static int vm_mmap_vnode(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
- int *, struct vnode *, vm_ooffset_t *, vm_object_t *, boolean_t *);
-static int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
- int *, struct cdev *, vm_ooffset_t *, vm_object_t *);
-static int vm_mmap_shm(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
- int *, struct shmfd *, vm_ooffset_t, vm_object_t *);
-
#ifndef _SYS_SYSPROTO_H_
struct sbrk_args {
int incr;
@@ -197,16 +190,10 @@ sys_mmap(td, uap)
struct thread *td;
struct mmap_args *uap;
{
-#ifdef HWPMC_HOOKS
- struct pmckern_map_in pkm;
-#endif
struct file *fp;
- struct vnode *vp;
vm_offset_t addr;
vm_size_t size, pageoff;
- vm_prot_t cap_maxprot, maxprot;
- void *handle;
- objtype_t handle_type;
+ vm_prot_t cap_maxprot;
int align, error, flags, prot;
off_t pos;
struct vmspace *vms = td->td_proc->p_vmspace;
@@ -329,19 +316,27 @@ sys_mmap(td, uap)
if (addr == 0 ||
(addr >= round_page((vm_offset_t)vms->vm_taddr) &&
addr < round_page((vm_offset_t)vms->vm_daddr +
- lim_max(td->td_proc, RLIMIT_DATA))))
+ lim_max_proc(td->td_proc, RLIMIT_DATA))))
addr = round_page((vm_offset_t)vms->vm_daddr +
- lim_max(td->td_proc, RLIMIT_DATA));
+ lim_max_proc(td->td_proc, RLIMIT_DATA));
PROC_UNLOCK(td->td_proc);
}
- if (flags & MAP_ANON) {
+ if (size == 0) {
+ /*
+ * Return success without mapping anything for old
+ * binaries that request a page-aligned mapping of
+ * length 0. For modern binaries, this function
+ * returns an error earlier.
+ */
+ error = 0;
+ } else if (flags & MAP_ANON) {
/*
* Mapping blank space is trivial.
+ *
+ * This relies on VM_PROT_* matching PROT_*.
*/
- handle = NULL;
- handle_type = OBJT_DEFAULT;
- maxprot = VM_PROT_ALL;
- cap_maxprot = VM_PROT_ALL;
+ error = vm_mmap_object(&vms->vm_map, &addr, size, prot,
+ VM_PROT_ALL, flags, NULL, pos, FALSE, td);
} else {
/*
* Mapping file, get fp for validation and don't let the
@@ -366,93 +361,12 @@ sys_mmap(td, uap)
error = EINVAL;
goto done;
}
- if (fp->f_type == DTYPE_SHM) {
- handle = fp->f_data;
- handle_type = OBJT_SWAP;
- maxprot = VM_PROT_NONE;
-
- /* FREAD should always be set. */
- if (fp->f_flag & FREAD)
- maxprot |= VM_PROT_EXECUTE | VM_PROT_READ;
- if (fp->f_flag & FWRITE)
- maxprot |= VM_PROT_WRITE;
- goto map;
- }
- if (fp->f_type != DTYPE_VNODE) {
- error = ENODEV;
- goto done;
- }
-#if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \
- defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4)
- /*
- * POSIX shared-memory objects are defined to have
- * kernel persistence, and are not defined to support
- * read(2)/write(2) -- or even open(2). Thus, we can
- * use MAP_ASYNC to trade on-disk coherence for speed.
- * The shm_open(3) library routine turns on the FPOSIXSHM
- * flag to request this behavior.
- */
- if (fp->f_flag & FPOSIXSHM)
- flags |= MAP_NOSYNC;
-#endif
- vp = fp->f_vnode;
- /*
- * Ensure that file and memory protections are
- * compatible. Note that we only worry about
- * writability if mapping is shared; in this case,
- * current and max prot are dictated by the open file.
- * XXX use the vnode instead? Problem is: what
- * credentials do we use for determination? What if
- * proc does a setuid?
- */
- if (vp->v_mount != NULL && vp->v_mount->mnt_flag & MNT_NOEXEC)
- maxprot = VM_PROT_NONE;
- else
- maxprot = VM_PROT_EXECUTE;
- if (fp->f_flag & FREAD) {
- maxprot |= VM_PROT_READ;
- } else if (prot & PROT_READ) {
- error = EACCES;
- goto done;
- }
- /*
- * If we are sharing potential changes (either via
- * MAP_SHARED or via the implicit sharing of character
- * device mappings), and we are trying to get write
- * permission although we opened it without asking
- * for it, bail out.
- */
- if ((flags & MAP_SHARED) != 0) {
- if ((fp->f_flag & FWRITE) != 0) {
- maxprot |= VM_PROT_WRITE;
- } else if ((prot & PROT_WRITE) != 0) {
- error = EACCES;
- goto done;
- }
- } else if (vp->v_type != VCHR || (fp->f_flag & FWRITE) != 0) {
- maxprot |= VM_PROT_WRITE;
- cap_maxprot |= VM_PROT_WRITE;
- }
- handle = (void *)vp;
- handle_type = OBJT_VNODE;
- }
-map:
- td->td_fpop = fp;
- maxprot &= cap_maxprot;
- /* This relies on VM_PROT_* matching PROT_*. */
- error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
- flags, handle_type, handle, pos);
- td->td_fpop = NULL;
-#ifdef HWPMC_HOOKS
- /* inform hwpmc(4) if an executable is being mapped */
- if (error == 0 && handle_type == OBJT_VNODE &&
- (prot & PROT_EXEC)) {
- pkm.pm_file = handle;
- pkm.pm_address = (uintptr_t) addr;
- PMC_CALL_HOOK(td, PMC_FN_MMAP, (void *) &pkm);
+ /* This relies on VM_PROT_* matching PROT_*. */
+ error = fo_mmap(fp, &vms->vm_map, &addr, size, prot,
+ cap_maxprot, flags, pos, td);
}
-#endif
+
if (error == 0)
td->td_retval[0] = (register_t) (addr + pageoff);
done:
@@ -1114,7 +1028,7 @@ vm_mlock(struct proc *proc, struct ucred *cred, const void *addr0, size_t len)
map = &proc->p_vmspace->vm_map;
PROC_LOCK(proc);
nsize = ptoa(npages + pmap_wired_count(map->pmap));
- if (nsize > lim_cur(proc, RLIMIT_MEMLOCK)) {
+ if (nsize > lim_cur_proc(proc, RLIMIT_MEMLOCK)) {
PROC_UNLOCK(proc);
return (ENOMEM);
}
@@ -1174,7 +1088,7 @@ sys_mlockall(td, uap)
*/
if (!old_mlock && uap->how & MCL_CURRENT) {
PROC_LOCK(td->td_proc);
- if (map->size > lim_cur(td->td_proc, RLIMIT_MEMLOCK)) {
+ if (map->size > lim_cur(td, RLIMIT_MEMLOCK)) {
PROC_UNLOCK(td->td_proc);
return (ENOMEM);
}
@@ -1311,9 +1225,6 @@ sys_munlock(td, uap)
*
* Helper function for vm_mmap. Perform sanity check specific for mmap
* operations on vnodes.
- *
- * For VCHR vnodes, the vnode lock is held over the call to
- * vm_mmap_cdev() to keep vp->v_rdev valid.
*/
int
vm_mmap_vnode(struct thread *td, vm_size_t objsize,
@@ -1360,12 +1271,6 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
*writecounted = TRUE;
vnode_pager_update_writecount(obj, 0, objsize);
}
- } else if (vp->v_type == VCHR) {
- error = vm_mmap_cdev(td, objsize, prot, maxprotp, flagsp,
- vp->v_rdev, foffp, objp);
- if (error == 0)
- goto mark_atime;
- goto done;
} else {
error = EINVAL;
goto done;
@@ -1373,13 +1278,14 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
if ((error = VOP_GETATTR(vp, &va, cred)))
goto done;
#ifdef MAC
- error = mac_vnode_check_mmap(cred, vp, prot, flags);
+ /* This relies on VM_PROT_* matching PROT_*. */
+ error = mac_vnode_check_mmap(cred, vp, (int)prot, flags);
if (error != 0)
goto done;
#endif
if ((flags & MAP_SHARED) != 0) {
if ((va.va_flags & (SF_SNAPSHOT|IMMUTABLE|APPEND)) != 0) {
- if (prot & PROT_WRITE) {
+ if (prot & VM_PROT_WRITE) {
error = EPERM;
goto done;
}
@@ -1414,7 +1320,6 @@ vm_mmap_vnode(struct thread *td, vm_size_t objsize,
*objp = obj;
*flagsp = flags;
-mark_atime:
vfs_mark_atime(vp, cred);
done:
@@ -1435,21 +1340,18 @@ done:
* operations on cdevs.
*/
int
-vm_mmap_cdev(struct thread *td, vm_size_t objsize,
- vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp,
- struct cdev *cdev, vm_ooffset_t *foff, vm_object_t *objp)
+vm_mmap_cdev(struct thread *td, vm_size_t objsize, vm_prot_t prot,
+ vm_prot_t *maxprotp, int *flagsp, struct cdev *cdev, struct cdevsw *dsw,
+ vm_ooffset_t *foff, vm_object_t *objp)
{
vm_object_t obj;
- struct cdevsw *dsw;
- int error, flags, ref;
+ int error, flags;
flags = *flagsp;
- dsw = dev_refthread(cdev, &ref);
- if (dsw == NULL)
- return (ENXIO);
if (dsw->d_flags & D_MMAP_ANON) {
- dev_relthread(cdev, ref);
+ *objp = NULL;
+ *foff = 0;
*maxprotp = VM_PROT_ALL;
*flagsp |= MAP_ANON;
return (0);
@@ -1458,24 +1360,18 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
* cdevs do not provide private mappings of any kind.
*/
if ((*maxprotp & VM_PROT_WRITE) == 0 &&
- (prot & PROT_WRITE) != 0) {
- dev_relthread(cdev, ref);
+ (prot & VM_PROT_WRITE) != 0)
return (EACCES);
- }
- if (flags & (MAP_PRIVATE|MAP_COPY)) {
- dev_relthread(cdev, ref);
+ if (flags & (MAP_PRIVATE|MAP_COPY))
return (EINVAL);
- }
/*
* Force device mappings to be shared.
*/
flags |= MAP_SHARED;
#ifdef MAC_XXX
- error = mac_cdev_check_mmap(td->td_ucred, cdev, prot);
- if (error != 0) {
- dev_relthread(cdev, ref);
+ error = mac_cdev_check_mmap(td->td_ucred, cdev, (int)prot);
+ if (error != 0)
return (error);
- }
#endif
/*
* First, try d_mmap_single(). If that is not implemented
@@ -1487,7 +1383,6 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
* XXX assumes VM_PROT_* == PROT_*
*/
error = dsw->d_mmap_single(cdev, foff, objsize, objp, (int)prot);
- dev_relthread(cdev, ref);
if (error != ENODEV)
return (error);
obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, *foff,
@@ -1500,63 +1395,93 @@ vm_mmap_cdev(struct thread *td, vm_size_t objsize,
}
/*
- * vm_mmap_shm()
- *
- * MPSAFE
+ * vm_mmap()
*
- * Helper function for vm_mmap. Perform sanity check specific for mmap
- * operations on shm file descriptors.
+ * Internal version of mmap used by exec, sys5 shared memory, and
+ * various device drivers. Handle is either a vnode pointer, a
+ * character device, or NULL for MAP_ANON.
*/
int
-vm_mmap_shm(struct thread *td, vm_size_t objsize,
- vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp,
- struct shmfd *shmfd, vm_ooffset_t foff, vm_object_t *objp)
+vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
+ vm_prot_t maxprot, int flags,
+ objtype_t handle_type, void *handle,
+ vm_ooffset_t foff)
{
+ vm_object_t object;
+ struct thread *td = curthread;
int error;
+ boolean_t writecounted;
- if ((*flagsp & MAP_SHARED) != 0 &&
- (*maxprotp & VM_PROT_WRITE) == 0 &&
- (prot & PROT_WRITE) != 0)
- return (EACCES);
-#ifdef MAC
- error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, *flagsp);
- if (error != 0)
- return (error);
-#endif
- error = shm_mmap(shmfd, objsize, foff, objp);
+ if (size == 0)
+ return (EINVAL);
+
+ size = round_page(size);
+ writecounted = FALSE;
+
+ /*
+ * Lookup/allocate object.
+ */
+ switch (handle_type) {
+ case OBJT_DEVICE: {
+ struct cdevsw *dsw;
+ struct cdev *cdev;
+ int ref;
+
+ cdev = handle;
+ dsw = dev_refthread(cdev, &ref);
+ if (dsw == NULL)
+ return (ENXIO);
+ error = vm_mmap_cdev(td, size, prot, &maxprot, &flags, cdev,
+ dsw, &foff, &object);
+ dev_relthread(cdev, ref);
+ break;
+ }
+ case OBJT_VNODE:
+ error = vm_mmap_vnode(td, size, prot, &maxprot, &flags,
+ handle, &foff, &object, &writecounted);
+ break;
+ case OBJT_DEFAULT:
+ if (handle == NULL) {
+ error = 0;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ error = EINVAL;
+ break;
+ }
if (error)
return (error);
- return (0);
+
+ error = vm_mmap_object(map, addr, size, prot, maxprot, flags, object,
+ foff, writecounted, td);
+ if (error != 0 && object != NULL) {
+ /*
+ * If this mapping was accounted for in the vnode's
+ * writecount, then undo that now.
+ */
+ if (writecounted)
+ vnode_pager_release_writecount(object, 0, size);
+ vm_object_deallocate(object);
+ }
+ return (error);
}
/*
- * vm_mmap()
- *
- * MPSAFE
- *
- * Internal version of mmap. Currently used by mmap, exec, and sys5
- * shared memory. Handle is either a vnode pointer or NULL for MAP_ANON.
+ * Internal version of mmap that maps a specific VM object into an
+ * map. Called by mmap for MAP_ANON, vm_mmap, shm_mmap, and vn_mmap.
*/
int
-vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
- vm_prot_t maxprot, int flags,
- objtype_t handle_type, void *handle,
- vm_ooffset_t foff)
+vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
+ vm_prot_t maxprot, int flags, vm_object_t object, vm_ooffset_t foff,
+ boolean_t writecounted, struct thread *td)
{
boolean_t fitit;
- vm_object_t object = NULL;
- struct thread *td = curthread;
int docow, error, findspace, rv;
- boolean_t writecounted;
-
- if (size == 0)
- return (0);
-
- size = round_page(size);
if (map == &td->td_proc->p_vmspace->vm_map) {
PROC_LOCK(td->td_proc);
- if (map->size + size > lim_cur(td->td_proc, RLIMIT_VMEM)) {
+ if (map->size + size > lim_cur_proc(td->td_proc, RLIMIT_VMEM)) {
PROC_UNLOCK(td->td_proc);
return (ENOMEM);
}
@@ -1566,7 +1491,7 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
}
if (!old_mlock && map->flags & MAP_WIREFUTURE) {
if (ptoa(pmap_wired_count(map->pmap)) + size >
- lim_cur(td->td_proc, RLIMIT_MEMLOCK)) {
+ lim_cur_proc(td->td_proc, RLIMIT_MEMLOCK)) {
racct_set_force(td->td_proc, RACCT_VMEM,
map->size);
PROC_UNLOCK(td->td_proc);
@@ -1586,11 +1511,11 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
/*
* We currently can only deal with page aligned file offsets.
- * The check is here rather than in the syscall because the
- * kernel calls this function internally for other mmaping
- * operations (such as in exec) and non-aligned offsets will
- * cause pmap inconsistencies...so we want to be sure to
- * disallow this in all cases.
+ * The mmap() system call already enforces this by subtracting
+ * the page offset from the file offset, but checking here
+ * catches errors in device drivers (e.g. d_single_mmap()
+ * callbacks) and other internal mapping requests (such as in
+ * exec).
*/
if (foff & PAGE_MASK)
return (EINVAL);
@@ -1603,44 +1528,11 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
return (EINVAL);
fitit = FALSE;
}
- writecounted = FALSE;
- /*
- * Lookup/allocate object.
- */
- switch (handle_type) {
- case OBJT_DEVICE:
- error = vm_mmap_cdev(td, size, prot, &maxprot, &flags,
- handle, &foff, &object);
- break;
- case OBJT_VNODE:
- error = vm_mmap_vnode(td, size, prot, &maxprot, &flags,
- handle, &foff, &object, &writecounted);
- break;
- case OBJT_SWAP:
- error = vm_mmap_shm(td, size, prot, &maxprot, &flags,
- handle, foff, &object);
- break;
- case OBJT_DEFAULT:
- if (handle == NULL) {
- error = 0;
- break;
- }
- /* FALLTHROUGH */
- default:
- error = EINVAL;
- break;
- }
- if (error)
- return (error);
if (flags & MAP_ANON) {
- object = NULL;
+ if (object != NULL || foff != 0)
+ return (EINVAL);
docow = 0;
- /*
- * Unnamed anonymous regions always start at 0.
- */
- if (handle == 0)
- foff = 0;
} else if (flags & MAP_PREFAULT_READ)
docow = MAP_PREFAULT;
else
@@ -1693,19 +1585,6 @@ vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
VM_MAP_WIRE_USER | ((flags & MAP_STACK) ?
VM_MAP_WIRE_HOLESOK : VM_MAP_WIRE_NOHOLES));
}
- } else {
- /*
- * If this mapping was accounted for in the vnode's
- * writecount, then undo that now.
- */
- if (writecounted)
- vnode_pager_release_writecount(object, 0, size);
- /*
- * Lose the object reference. Will destroy the
- * object if it's an unnamed anonymous mapping
- * or named anonymous without other references.
- */
- vm_object_deallocate(object);
}
return (vm_mmap_to_errno(rv));
}
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 78cea70a9f07..c7f31539a6ba 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
+#include <sys/user.h>
#include <sys/vnode.h>
#include <sys/vmmeter.h>
#include <sys/sx.h>
@@ -2045,7 +2046,7 @@ vm_object_page_cache(vm_object_t object, vm_pindex_t start, vm_pindex_t end)
boolean_t
vm_object_populate(vm_object_t object, vm_pindex_t start, vm_pindex_t end)
{
- vm_page_t m, ma[1];
+ vm_page_t m;
vm_pindex_t pindex;
int rv;
@@ -2053,11 +2054,7 @@ vm_object_populate(vm_object_t object, vm_pindex_t start, vm_pindex_t end)
for (pindex = start; pindex < end; pindex++) {
m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL);
if (m->valid != VM_PAGE_BITS_ALL) {
- ma[0] = m;
- rv = vm_pager_get_pages(object, ma, 1, 0);
- m = vm_page_lookup(object, pindex);
- if (m == NULL)
- break;
+ rv = vm_pager_get_pages(object, &m, 1, 0);
if (rv != VM_PAGER_OK) {
vm_page_lock(m);
vm_page_free(m);
@@ -2286,6 +2283,154 @@ next_page:
}
}
+struct vnode *
+vm_object_vnode(vm_object_t object)
+{
+
+ VM_OBJECT_ASSERT_LOCKED(object);
+ if (object->type == OBJT_VNODE)
+ return (object->handle);
+ if (object->type == OBJT_SWAP && (object->flags & OBJ_TMPFS) != 0)
+ return (object->un_pager.swp.swp_tmpfs);
+ return (NULL);
+}
+
+static int
+sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
+{
+ struct kinfo_vmobject kvo;
+ char *fullpath, *freepath;
+ struct vnode *vp;
+ struct vattr va;
+ vm_object_t obj;
+ vm_page_t m;
+ int count, error;
+
+ if (req->oldptr == NULL) {
+ /*
+ * If an old buffer has not been provided, generate an
+ * estimate of the space needed for a subsequent call.
+ */
+ mtx_lock(&vm_object_list_mtx);
+ count = 0;
+ TAILQ_FOREACH(obj, &vm_object_list, object_list) {
+ if (obj->type == OBJT_DEAD)
+ continue;
+ count++;
+ }
+ mtx_unlock(&vm_object_list_mtx);
+ return (SYSCTL_OUT(req, NULL, sizeof(struct kinfo_vmobject) *
+ count * 11 / 10));
+ }
+
+ error = 0;
+
+ /*
+ * VM objects are type stable and are never removed from the
+ * list once added. This allows us to safely read obj->object_list
+ * after reacquiring the VM object lock.
+ */
+ mtx_lock(&vm_object_list_mtx);
+ TAILQ_FOREACH(obj, &vm_object_list, object_list) {
+ if (obj->type == OBJT_DEAD)
+ continue;
+ VM_OBJECT_RLOCK(obj);
+ if (obj->type == OBJT_DEAD) {
+ VM_OBJECT_RUNLOCK(obj);
+ continue;
+ }
+ mtx_unlock(&vm_object_list_mtx);
+ kvo.kvo_size = ptoa(obj->size);
+ kvo.kvo_resident = obj->resident_page_count;
+ kvo.kvo_ref_count = obj->ref_count;
+ kvo.kvo_shadow_count = obj->shadow_count;
+ kvo.kvo_memattr = obj->memattr;
+ kvo.kvo_active = 0;
+ kvo.kvo_inactive = 0;
+ TAILQ_FOREACH(m, &obj->memq, listq) {
+ /*
+ * A page may belong to the object but be
+ * dequeued and set to PQ_NONE while the
+ * object lock is not held. This makes the
+ * reads of m->queue below racy, and we do not
+ * count pages set to PQ_NONE. However, this
+ * sysctl is only meant to give an
+ * approximation of the system anyway.
+ */
+ if (m->queue == PQ_ACTIVE)
+ kvo.kvo_active++;
+ else if (m->queue == PQ_INACTIVE)
+ kvo.kvo_inactive++;
+ }
+
+ kvo.kvo_vn_fileid = 0;
+ kvo.kvo_vn_fsid = 0;
+ freepath = NULL;
+ fullpath = "";
+ vp = NULL;
+ switch (obj->type) {
+ case OBJT_DEFAULT:
+ kvo.kvo_type = KVME_TYPE_DEFAULT;
+ break;
+ case OBJT_VNODE:
+ kvo.kvo_type = KVME_TYPE_VNODE;
+ vp = obj->handle;
+ vref(vp);
+ break;
+ case OBJT_SWAP:
+ kvo.kvo_type = KVME_TYPE_SWAP;
+ break;
+ case OBJT_DEVICE:
+ kvo.kvo_type = KVME_TYPE_DEVICE;
+ break;
+ case OBJT_PHYS:
+ kvo.kvo_type = KVME_TYPE_PHYS;
+ break;
+ case OBJT_DEAD:
+ kvo.kvo_type = KVME_TYPE_DEAD;
+ break;
+ case OBJT_SG:
+ kvo.kvo_type = KVME_TYPE_SG;
+ break;
+ case OBJT_MGTDEVICE:
+ kvo.kvo_type = KVME_TYPE_MGTDEVICE;
+ break;
+ default:
+ kvo.kvo_type = KVME_TYPE_UNKNOWN;
+ break;
+ }
+ VM_OBJECT_RUNLOCK(obj);
+ if (vp != NULL) {
+ vn_fullpath(curthread, vp, &fullpath, &freepath);
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ if (VOP_GETATTR(vp, &va, curthread->td_ucred) == 0) {
+ kvo.kvo_vn_fileid = va.va_fileid;
+ kvo.kvo_vn_fsid = va.va_fsid;
+ }
+ vput(vp);
+ }
+
+ strlcpy(kvo.kvo_path, fullpath, sizeof(kvo.kvo_path));
+ if (freepath != NULL)
+ free(freepath, M_TEMP);
+
+ /* Pack record size down */
+ kvo.kvo_structsize = offsetof(struct kinfo_vmobject, kvo_path) +
+ strlen(kvo.kvo_path) + 1;
+ kvo.kvo_structsize = roundup(kvo.kvo_structsize,
+ sizeof(uint64_t));
+ error = SYSCTL_OUT(req, &kvo, kvo.kvo_structsize);
+ mtx_lock(&vm_object_list_mtx);
+ if (error)
+ break;
+ }
+ mtx_unlock(&vm_object_list_mtx);
+ return (error);
+}
+SYSCTL_PROC(_vm, OID_AUTO, objects, CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_SKIP |
+ CTLFLAG_MPSAFE, NULL, 0, sysctl_vm_object_list, "S,kinfo_vmobject",
+ "List of VM objects");
+
#include "opt_ddb.h"
#ifdef DDB
#include <sys/kernel.h>
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index 731c9e3e8d71..1f591568137c 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -322,6 +322,7 @@ boolean_t vm_object_sync(vm_object_t, vm_ooffset_t, vm_size_t, boolean_t,
boolean_t);
void vm_object_unwire(vm_object_t object, vm_ooffset_t offset,
vm_size_t length, uint8_t queue);
+struct vnode *vm_object_vnode(vm_object_t object);
#endif /* _KERNEL */
#endif /* _VM_OBJECT_ */
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index b3b36d66e203..3b58fb7f55e9 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -1827,6 +1827,7 @@ vm_page_alloc_contig_vdrop(struct spglist *lst)
*
* optional allocation flags:
* VM_ALLOC_NOBUSY do not exclusive busy the page
+ * VM_ALLOC_NODUMP do not include the page in a kernel core dump
* VM_ALLOC_NOOBJ page is not associated with an object and
* should not be exclusive busy
* VM_ALLOC_SBUSY shared busy the allocated page
@@ -2707,7 +2708,6 @@ vm_page_cache(vm_page_t m)
#else
if (TRUE) {
#endif
- vm_phys_set_pool(VM_FREEPOOL_CACHE, m, 0);
vm_phys_free_pages(m, 0);
}
vm_page_free_wakeup();
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 2f57579da353..71d76d495ec2 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1851,7 +1851,7 @@ again:
/*
* get a limit
*/
- lim_rlimit(p, RLIMIT_RSS, &rsslim);
+ lim_rlimit_proc(p, RLIMIT_RSS, &rsslim);
limit = OFF_TO_IDX(
qmin(rsslim.rlim_cur, rsslim.rlim_max));
diff --git a/sys/vm/vm_reserv.c b/sys/vm/vm_reserv.c
index b74c768f48e1..2cfc630026de 100644
--- a/sys/vm/vm_reserv.c
+++ b/sys/vm/vm_reserv.c
@@ -801,9 +801,6 @@ vm_reserv_free_page(vm_page_t m)
rv = vm_reserv_from_page(m);
if (rv->object == NULL)
return (FALSE);
- if ((m->flags & PG_CACHED) != 0 && m->pool != VM_FREEPOOL_CACHE)
- vm_phys_set_pool(VM_FREEPOOL_CACHE, rv->pages,
- VM_LEVEL_0_ORDER);
vm_reserv_depopulate(rv, m - rv->pages);
return (TRUE);
}
diff --git a/sys/vm/vm_unix.c b/sys/vm/vm_unix.c
index cc77ff73b10e..201c13bf933e 100644
--- a/sys/vm/vm_unix.c
+++ b/sys/vm/vm_unix.c
@@ -83,11 +83,9 @@ sys_obreak(td, uap)
int error = 0;
boolean_t do_map_wirefuture;
- PROC_LOCK(td->td_proc);
- datalim = lim_cur(td->td_proc, RLIMIT_DATA);
- lmemlim = lim_cur(td->td_proc, RLIMIT_MEMLOCK);
- vmemlim = lim_cur(td->td_proc, RLIMIT_VMEM);
- PROC_UNLOCK(td->td_proc);
+ datalim = lim_cur(td, RLIMIT_DATA);
+ lmemlim = lim_cur(td, RLIMIT_MEMLOCK);
+ vmemlim = lim_cur(td, RLIMIT_VMEM);
do_map_wirefuture = FALSE;
new = round_page((vm_offset_t)uap->nsize);
diff --git a/sys/x86/acpica/madt.c b/sys/x86/acpica/madt.c
index 149e5ddd2285..e81235814f63 100644
--- a/sys/x86/acpica/madt.c
+++ b/sys/x86/acpica/madt.c
@@ -56,8 +56,8 @@ static struct {
} *ioapics;
static struct lapic_info {
- u_int la_enabled:1;
- u_int la_acpi_id:8;
+ u_int la_enabled;
+ u_int la_acpi_id;
} lapics[MAX_APIC_ID + 1];
int madt_found_sci_override;
@@ -255,34 +255,48 @@ madt_walk_table(acpi_subtable_handler *handler, void *arg)
}
static void
+madt_add_cpu(u_int acpi_id, u_int apic_id, u_int flags)
+{
+ struct lapic_info *la;
+
+ /*
+ * The MADT does not include a BSP flag, so we have to let the
+ * MP code figure out which CPU is the BSP on its own.
+ */
+ if (bootverbose)
+ printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n",
+ apic_id, acpi_id, flags & ACPI_MADT_ENABLED ?
+ "enabled" : "disabled");
+ if (!(flags & ACPI_MADT_ENABLED))
+ return;
+ if (apic_id > MAX_APIC_ID) {
+ printf("MADT: Ignoring local APIC ID %u (too high)\n",
+ apic_id);
+ return;
+ }
+
+ la = &lapics[apic_id];
+ KASSERT(la->la_enabled == 0, ("Duplicate local APIC ID %u", apic_id));
+ la->la_enabled = 1;
+ la->la_acpi_id = acpi_id;
+ lapic_create(apic_id, 0);
+}
+
+static void
madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
{
ACPI_MADT_LOCAL_APIC *proc;
- struct lapic_info *la;
+ ACPI_MADT_LOCAL_X2APIC *x2apic;
switch (entry->Type) {
case ACPI_MADT_TYPE_LOCAL_APIC:
- /*
- * The MADT does not include a BSP flag, so we have to
- * let the MP code figure out which CPU is the BSP on
- * its own.
- */
proc = (ACPI_MADT_LOCAL_APIC *)entry;
- if (bootverbose)
- printf("MADT: Found CPU APIC ID %u ACPI ID %u: %s\n",
- proc->Id, proc->ProcessorId,
- (proc->LapicFlags & ACPI_MADT_ENABLED) ?
- "enabled" : "disabled");
- if (!(proc->LapicFlags & ACPI_MADT_ENABLED))
- break;
- if (proc->Id > MAX_APIC_ID)
- panic("%s: CPU ID %u too high", __func__, proc->Id);
- la = &lapics[proc->Id];
- KASSERT(la->la_enabled == 0,
- ("Duplicate local APIC ID %u", proc->Id));
- la->la_enabled = 1;
- la->la_acpi_id = proc->ProcessorId;
- lapic_create(proc->Id, 0);
+ madt_add_cpu(proc->ProcessorId, proc->Id, proc->LapicFlags);
+ break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC:
+ x2apic = (ACPI_MADT_LOCAL_X2APIC *)entry;
+ madt_add_cpu(x2apic->Uid, x2apic->LocalApicId,
+ x2apic->LapicFlags);
break;
}
}
@@ -551,29 +565,44 @@ madt_parse_nmi(ACPI_MADT_NMI_SOURCE *nmi)
* Parse an entry for an NMI routed to a local APIC LVT pin.
*/
static void
-madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi)
+madt_handle_local_nmi(u_int acpi_id, UINT8 Lint, UINT16 IntiFlags)
{
u_int apic_id, pin;
- if (nmi->ProcessorId == 0xff)
+ if (acpi_id == 0xffffffff)
apic_id = APIC_ID_ALL;
- else if (madt_find_cpu(nmi->ProcessorId, &apic_id) != 0) {
+ else if (madt_find_cpu(acpi_id, &apic_id) != 0) {
if (bootverbose)
printf("MADT: Ignoring local NMI routed to "
- "ACPI CPU %u\n", nmi->ProcessorId);
+ "ACPI CPU %u\n", acpi_id);
return;
}
- if (nmi->Lint == 0)
+ if (Lint == 0)
pin = APIC_LVT_LINT0;
else
pin = APIC_LVT_LINT1;
lapic_set_lvt_mode(apic_id, pin, APIC_LVT_DM_NMI);
- if (!(nmi->IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
+ if (!(IntiFlags & ACPI_MADT_TRIGGER_CONFORMS))
lapic_set_lvt_triggermode(apic_id, pin,
- interrupt_trigger(nmi->IntiFlags, 0));
- if (!(nmi->IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
+ interrupt_trigger(IntiFlags, 0));
+ if (!(IntiFlags & ACPI_MADT_POLARITY_CONFORMS))
lapic_set_lvt_polarity(apic_id, pin,
- interrupt_polarity(nmi->IntiFlags, 0));
+ interrupt_polarity(IntiFlags, 0));
+}
+
+static void
+madt_parse_local_nmi(ACPI_MADT_LOCAL_APIC_NMI *nmi)
+{
+
+ madt_handle_local_nmi(nmi->ProcessorId == 0xff ? 0xffffffff :
+ nmi->ProcessorId, nmi->Lint, nmi->IntiFlags);
+}
+
+static void
+madt_parse_local_x2apic_nmi(ACPI_MADT_LOCAL_X2APIC_NMI *nmi)
+{
+
+ madt_handle_local_nmi(nmi->Uid, nmi->Lint, nmi->IntiFlags);
}
/*
@@ -594,6 +623,10 @@ madt_parse_ints(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
madt_parse_local_nmi((ACPI_MADT_LOCAL_APIC_NMI *)entry);
break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+ madt_parse_local_x2apic_nmi(
+ (ACPI_MADT_LOCAL_X2APIC_NMI *)entry);
+ break;
}
}
diff --git a/sys/x86/iommu/busdma_dmar.c b/sys/x86/iommu/busdma_dmar.c
index 96b0bcea394f..3ef81075a349 100644
--- a/sys/x86/iommu/busdma_dmar.c
+++ b/sys/x86/iommu/busdma_dmar.c
@@ -818,7 +818,6 @@ dmar_bus_task_dmamap(void *arg, int pending)
struct bus_dma_tag_dmar *tag;
struct bus_dmamap_dmar *map;
struct dmar_unit *unit;
- struct dmar_ctx *ctx;
unit = arg;
DMAR_LOCK(unit);
@@ -826,7 +825,6 @@ dmar_bus_task_dmamap(void *arg, int pending)
TAILQ_REMOVE(&unit->delayed_maps, map, delay_link);
DMAR_UNLOCK(unit);
tag = map->tag;
- ctx = map->tag->ctx;
map->cansleep = true;
map->locked = false;
bus_dmamap_load_mem((bus_dma_tag_t)tag, (bus_dmamap_t)map,
@@ -847,9 +845,7 @@ dmar_bus_task_dmamap(void *arg, int pending)
static void
dmar_bus_schedule_dmamap(struct dmar_unit *unit, struct bus_dmamap_dmar *map)
{
- struct dmar_ctx *ctx;
- ctx = map->tag->ctx;
map->locked = false;
DMAR_LOCK(unit);
TAILQ_INSERT_TAIL(&unit->delayed_maps, map, delay_link);
diff --git a/sys/x86/iommu/intel_idpgtbl.c b/sys/x86/iommu/intel_idpgtbl.c
index 6621b1720215..b9492dd6456a 100644
--- a/sys/x86/iommu/intel_idpgtbl.c
+++ b/sys/x86/iommu/intel_idpgtbl.c
@@ -108,7 +108,7 @@ static void
ctx_idmap_nextlvl(struct idpgtbl *tbl, int lvl, vm_pindex_t idx,
dmar_gaddr_t addr)
{
- vm_page_t m, m1;
+ vm_page_t m1;
dmar_pte_t *pte;
struct sf_buf *sf;
dmar_gaddr_t f, pg_sz;
@@ -118,7 +118,7 @@ ctx_idmap_nextlvl(struct idpgtbl *tbl, int lvl, vm_pindex_t idx,
VM_OBJECT_ASSERT_LOCKED(tbl->pgtbl_obj);
if (addr >= tbl->maxaddr)
return;
- m = dmar_pgalloc(tbl->pgtbl_obj, idx, DMAR_PGF_OBJL | DMAR_PGF_WAITOK |
+ (void)dmar_pgalloc(tbl->pgtbl_obj, idx, DMAR_PGF_OBJL | DMAR_PGF_WAITOK |
DMAR_PGF_ZERO);
base = idx * DMAR_NPTEPG + 1; /* Index of the first child page of idx */
pg_sz = pglvl_page_size(tbl->pglvl, lvl);
@@ -598,7 +598,7 @@ ctx_unmap_buf_locked(struct dmar_ctx *ctx, dmar_gaddr_t base,
dmar_pte_t *pte;
struct sf_buf *sf;
vm_pindex_t idx;
- dmar_gaddr_t pg_sz, base1, size1;
+ dmar_gaddr_t pg_sz;
int lvl;
DMAR_CTX_ASSERT_PGLOCKED(ctx);
@@ -625,8 +625,6 @@ ctx_unmap_buf_locked(struct dmar_ctx *ctx, dmar_gaddr_t base,
KASSERT((flags & ~DMAR_PGF_WAITOK) == 0, ("invalid flags %x", flags));
pg_sz = 0; /* silence gcc */
- base1 = base;
- size1 = size;
flags |= DMAR_PGF_OBJL;
TD_PREP_PINNED_ASSERT;
diff --git a/sys/x86/iommu/intel_qi.c b/sys/x86/iommu/intel_qi.c
index ce7b041d24c1..293e2be32a9f 100644
--- a/sys/x86/iommu/intel_qi.c
+++ b/sys/x86/iommu/intel_qi.c
@@ -411,6 +411,7 @@ dmar_init_qi(struct dmar_unit *unit)
ics = DMAR_ICS_IWC;
dmar_write4(unit, DMAR_ICS_REG, ics);
}
+ dmar_enable_qi_intr(unit);
DMAR_UNLOCK(unit);
return (0);
@@ -434,6 +435,7 @@ dmar_fini_qi(struct dmar_unit *unit)
dmar_qi_advance_tail(unit);
dmar_qi_wait_for_seq(unit, &gseq, false);
/* only after the quisce, disable queue */
+ dmar_disable_qi_intr(unit);
dmar_disable_qi(unit);
KASSERT(unit->inv_seq_waiters == 0,
("dmar%d: waiters on disabled queue", unit->unit));
diff --git a/sys/x86/x86/identcpu.c b/sys/x86/x86/identcpu.c
index 9f39d1c82af8..548da4a0e10a 100644
--- a/sys/x86/x86/identcpu.c
+++ b/sys/x86/x86/identcpu.c
@@ -903,6 +903,9 @@ printcpuinfo(void)
"\013INVPCID"
/* Restricted Transactional Memory */
"\014RTM"
+ "\015PQM"
+ "\016NFPUSG"
+ "\020PQE"
/* Intel Memory Protection Extensions */
"\017MPX"
/* AVX512 Foundation */
@@ -922,6 +925,16 @@ printcpuinfo(void)
);
}
+ if (cpu_stdext_feature2 != 0) {
+ printf("\n Structured Extended Features2=0x%b",
+ cpu_stdext_feature2,
+ "\020"
+ "\001PREFETCHWT1"
+ "\004PKU"
+ "\005OSPKE"
+ );
+ }
+
if ((cpu_feature2 & CPUID2_XSAVE) != 0) {
cpuid_count(0xd, 0x1, regs);
if (regs[0] != 0) {
@@ -1357,6 +1370,7 @@ identify_cpu(void)
cpu_stdext_disable = 0;
TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable);
cpu_stdext_feature &= ~cpu_stdext_disable;
+ cpu_stdext_feature2 = regs[2];
}
#ifdef __i386__
@@ -1701,18 +1715,39 @@ print_INTEL_TLB(u_int data)
case 0x8:
printf("1st-level instruction cache: 16 KB, 4-way set associative, 32 byte line size\n");
break;
+ case 0x9:
+ printf("1st-level instruction cache: 32 KB, 4-way set associative, 64 byte line size\n");
+ break;
case 0xa:
printf("1st-level data cache: 8 KB, 2-way set associative, 32 byte line size\n");
break;
+ case 0xb:
+ printf("Instruction TLB: 4 MByte pages, 4-way set associative, 4 entries\n");
+ break;
case 0xc:
printf("1st-level data cache: 16 KB, 4-way set associative, 32 byte line size\n");
break;
+ case 0xd:
+ printf("1st-level data cache: 16 KBytes, 4-way set associative, 64 byte line size");
+ break;
+ case 0xe:
+ printf("1st-level data cache: 24 KBytes, 6-way set associative, 64 byte line size\n");
+ break;
+ case 0x1d:
+ printf("2nd-level cache: 128 KBytes, 2-way set associative, 64 byte line size\n");
+ break;
+ case 0x21:
+ printf("2nd-level cache: 256 KBytes, 8-way set associative, 64 byte line size\n");
+ break;
case 0x22:
printf("3rd-level cache: 512 KB, 4-way set associative, sectored cache, 64 byte line size\n");
break;
case 0x23:
printf("3rd-level cache: 1 MB, 8-way set associative, sectored cache, 64 byte line size\n");
break;
+ case 0x24:
+ printf("2nd-level cache: 1 MBytes, 16-way set associative, 64 byte line size\n");
+ break;
case 0x25:
printf("3rd-level cache: 2 MB, 8-way set associative, sectored cache, 64 byte line size\n");
break;
@@ -1725,13 +1760,13 @@ print_INTEL_TLB(u_int data)
case 0x30:
printf("1st-level instruction cache: 32 KB, 8-way set associative, 64 byte line size\n");
break;
- case 0x39:
+ case 0x39: /* De-listed in SDM rev. 54 */
printf("2nd-level cache: 128 KB, 4-way set associative, sectored cache, 64 byte line size\n");
break;
- case 0x3b:
+ case 0x3b: /* De-listed in SDM rev. 54 */
printf("2nd-level cache: 128 KB, 2-way set associative, sectored cache, 64 byte line size\n");
break;
- case 0x3c:
+ case 0x3c: /* De-listed in SDM rev. 54 */
printf("2nd-level cache: 256 KB, 4-way set associative, sectored cache, 64 byte line size\n");
break;
case 0x41:
@@ -1755,6 +1790,34 @@ print_INTEL_TLB(u_int data)
case 0x47:
printf("3rd-level cache: 8 MB, 8-way set associative, 64 byte line size\n");
break;
+ case 0x48:
+ printf("2nd-level cache: 3MByte, 12-way set associative, 64 byte line size\n");
+ break;
+ case 0x49:
+ if (CPUID_TO_FAMILY(cpu_id) == 0xf &&
+ CPUID_TO_MODEL(cpu_id) == 0x6)
+ printf("3rd-level cache: 4MB, 16-way set associative, 64-byte line size\n");
+ else
+ printf("2nd-level cache: 4 MByte, 16-way set associative, 64 byte line size");
+ break;
+ case 0x4a:
+ printf("3rd-level cache: 6MByte, 12-way set associative, 64 byte line size\n");
+ break;
+ case 0x4b:
+ printf("3rd-level cache: 8MByte, 16-way set associative, 64 byte line size\n");
+ break;
+ case 0x4c:
+ printf("3rd-level cache: 12MByte, 12-way set associative, 64 byte line size\n");
+ break;
+ case 0x4d:
+ printf("3rd-level cache: 16MByte, 16-way set associative, 64 byte line size\n");
+ break;
+ case 0x4e:
+ printf("2nd-level cache: 6MByte, 24-way set associative, 64 byte line size\n");
+ break;
+ case 0x4f:
+ printf("Instruction TLB: 4 KByte pages, 32 entries\n");
+ break;
case 0x50:
printf("Instruction TLB: 4 KB, 2 MB or 4 MB pages, fully associative, 64 entries\n");
break;
@@ -1764,6 +1827,21 @@ print_INTEL_TLB(u_int data)
case 0x52:
printf("Instruction TLB: 4 KB, 2 MB or 4 MB pages, fully associative, 256 entries\n");
break;
+ case 0x55:
+ printf("Instruction TLB: 2-MByte or 4-MByte pages, fully associative, 7 entries\n");
+ break;
+ case 0x56:
+ printf("Data TLB0: 4 MByte pages, 4-way set associative, 16 entries\n");
+ break;
+ case 0x57:
+ printf("Data TLB0: 4 KByte pages, 4-way associative, 16 entries\n");
+ break;
+ case 0x59:
+ printf("Data TLB0: 4 KByte pages, fully associative, 16 entries\n");
+ break;
+ case 0x5a:
+ printf("Data TLB0: 2-MByte or 4 MByte pages, 4-way set associative, 32 entries\n");
+ break;
case 0x5b:
printf("Data TLB: 4 KB or 4 MB pages, fully associative, 64 entries\n");
break;
@@ -1776,6 +1854,12 @@ print_INTEL_TLB(u_int data)
case 0x60:
printf("1st-level data cache: 16 KB, 8-way set associative, sectored cache, 64 byte line size\n");
break;
+ case 0x61:
+ printf("Instruction TLB: 4 KByte pages, fully associative, 48 entries\n");
+ break;
+ case 0x63:
+ printf("Data TLB: 1 GByte pages, 4-way set associative, 4 entries\n");
+ break;
case 0x66:
printf("1st-level data cache: 8 KB, 4-way set associative, sectored cache, 64 byte line size\n");
break;
@@ -1794,6 +1878,9 @@ print_INTEL_TLB(u_int data)
case 0x72:
printf("Trace cache: 32K-uops, 8-way set associative\n");
break;
+ case 0x76:
+ printf("Instruction TLB: 2M/4M pages, fully associative, 8 entries\n");
+ break;
case 0x78:
printf("2nd-level cache: 1 MB, 4-way set associative, 64-byte line size\n");
break;
@@ -1815,6 +1902,9 @@ print_INTEL_TLB(u_int data)
case 0x7f:
printf("2nd-level cache: 512-KB, 2-way set associative, 64-byte line size\n");
break;
+ case 0x80:
+ printf("2nd-level cache: 512 KByte, 8-way set associative, 64-byte line size\n");
+ break;
case 0x82:
printf("2nd-level cache: 256 KB, 8-way set associative, 32 byte line size\n");
break;
@@ -1833,12 +1923,99 @@ print_INTEL_TLB(u_int data)
case 0x87:
printf("2nd-level cache: 1 MB, 8-way set associative, 64 byte line size\n");
break;
+ case 0xa0:
+ printf("DTLB: 4k pages, fully associative, 32 entries\n");
+ break;
case 0xb0:
printf("Instruction TLB: 4 KB Pages, 4-way set associative, 128 entries\n");
break;
+ case 0xb1:
+ printf("Instruction TLB: 2M pages, 4-way, 8 entries or 4M pages, 4-way, 4 entries\n");
+ break;
+ case 0xb2:
+ printf("Instruction TLB: 4KByte pages, 4-way set associative, 64 entries\n");
+ break;
case 0xb3:
printf("Data TLB: 4 KB Pages, 4-way set associative, 128 entries\n");
break;
+ case 0xb4:
+ printf("Data TLB1: 4 KByte pages, 4-way associative, 256 entries\n");
+ break;
+ case 0xb5:
+ printf("Instruction TLB: 4KByte pages, 8-way set associative, 64 entries\n");
+ break;
+ case 0xb6:
+ printf("Instruction TLB: 4KByte pages, 8-way set associative, 128 entries\n");
+ break;
+ case 0xba:
+ printf("Data TLB1: 4 KByte pages, 4-way associative, 64 entries\n");
+ break;
+ case 0xc0:
+ printf("Data TLB: 4 KByte and 4 MByte pages, 4-way associative, 8 entries\n");
+ break;
+ case 0xc1:
+ printf("Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries\n");
+ break;
+ case 0xc2:
+ printf("DTLB: 4 KByte/2 MByte pages, 4-way associative, 16 entries\n");
+ break;
+ case 0xc3:
+ printf("Shared 2nd-Level TLB: 4 KByte /2 MByte pages, 6-way associative, 1536 entries. Also 1GBbyte pages, 4-way, 16 entries\n");
+ break;
+ case 0xca:
+ printf("Shared 2nd-Level TLB: 4 KByte pages, 4-way associative, 512 entries\n");
+ break;
+ case 0xd0:
+ printf("3rd-level cache: 512 KByte, 4-way set associative, 64 byte line size\n");
+ break;
+ case 0xd1:
+ printf("3rd-level cache: 1 MByte, 4-way set associative, 64 byte line size\n");
+ break;
+ case 0xd2:
+ printf("3rd-level cache: 2 MByte, 4-way set associative, 64 byte line size\n");
+ break;
+ case 0xd6:
+ printf("3rd-level cache: 1 MByte, 8-way set associative, 64 byte line size\n");
+ break;
+ case 0xd7:
+ printf("3rd-level cache: 2 MByte, 8-way set associative, 64 byte line size\n");
+ break;
+ case 0xd8:
+ printf("3rd-level cache: 4 MByte, 8-way set associative, 64 byte line size\n");
+ break;
+ case 0xdc:
+ printf("3rd-level cache: 1.5 MByte, 12-way set associative, 64 byte line size\n");
+ break;
+ case 0xdd:
+ printf("3rd-level cache: 3 MByte, 12-way set associative, 64 byte line size\n");
+ break;
+ case 0xde:
+ printf("3rd-level cache: 6 MByte, 12-way set associative, 64 byte line size\n");
+ break;
+ case 0xe2:
+ printf("3rd-level cache: 2 MByte, 16-way set associative, 64 byte line size\n");
+ break;
+ case 0xe3:
+ printf("3rd-level cache: 4 MByte, 16-way set associative, 64 byte line size\n");
+ break;
+ case 0xe4:
+ printf("3rd-level cache: 8 MByte, 16-way set associative, 64 byte line size\n");
+ break;
+ case 0xea:
+ printf("3rd-level cache: 12MByte, 24-way set associative, 64 byte line size\n");
+ break;
+ case 0xeb:
+ printf("3rd-level cache: 18MByte, 24-way set associative, 64 byte line size\n");
+ break;
+ case 0xec:
+ printf("3rd-level cache: 24MByte, 24-way set associative, 64 byte line size\n");
+ break;
+ case 0xf0:
+ printf("64-Byte prefetching\n");
+ break;
+ case 0xf1:
+ printf("128-Byte prefetching\n");
+ break;
}
}
diff --git a/sys/x86/xen/xenpv.c b/sys/x86/xen/xenpv.c
index 2e4a9fea8f9a..50fd9df14912 100644
--- a/sys/x86/xen/xenpv.c
+++ b/sys/x86/xen/xenpv.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/pcpu.h>
#include <sys/rman.h>
#include <sys/smp.h>
+#include <sys/limits.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -72,7 +73,11 @@ xenpv_identify(driver_t *driver, device_t parent)
if (devclass_get_device(xenpv_devclass, 0))
return;
- if (BUS_ADD_CHILD(parent, 0, "xenpv", 0) == NULL)
+ /*
+ * The xenpv bus should be the last to attach in order
+ * to properly detect if an ISA bus has already been added.
+ */
+ if (BUS_ADD_CHILD(parent, UINT_MAX, "xenpv", 0) == NULL)
panic("Unable to attach xenpv bus.");
}
diff --git a/sys/xen/blkif.h b/sys/xen/blkif.h
index 48b71ea7f544..8a19d5d01d87 100644
--- a/sys/xen/blkif.h
+++ b/sys/xen/blkif.h
@@ -46,7 +46,7 @@ struct blkif_x86_32_request {
blkif_vdev_t handle; /* only for read/write requests */
uint64_t id; /* private guest value, echoed in resp */
blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK];
+ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
};
struct blkif_x86_32_response {
uint64_t id; /* copied from request */
@@ -64,7 +64,7 @@ struct blkif_x86_64_request {
blkif_vdev_t handle; /* only for read/write requests */
uint64_t __attribute__((__aligned__(8))) id;
blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK];
+ struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
};
struct blkif_x86_64_response {
uint64_t __attribute__((__aligned__(8))) id;
@@ -114,7 +114,7 @@ enum blkif_protocol {
static void inline blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_request_t *src)
{
- int i, n = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
+ int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
dst->operation = src->operation;
dst->nr_segments = src->nr_segments;
dst->handle = src->handle;
@@ -129,7 +129,7 @@ static void inline blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_reque
static void inline blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_request_t *src)
{
- int i, n = BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK;
+ int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
dst->operation = src->operation;
dst->nr_segments = src->nr_segments;
dst->handle = src->handle;
diff --git a/sys/xen/interface/io/blkif.h b/sys/xen/interface/io/blkif.h
index 9155662fcc5b..b72577648072 100644
--- a/sys/xen/interface/io/blkif.h
+++ b/sys/xen/interface/io/blkif.h
@@ -457,21 +457,9 @@
#define BLKIF_OP_DISCARD 5
/*
- * Maximum scatter/gather segments associated with a request header block.
- * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE.
- * NB. This could be 12 if the ring indexes weren't stored in the same page.
- */
-#define BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK 11
-
-/*
- * Maximum scatter/gather segments associated with a segment block.
- */
-#define BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK 14
-
-/*
* Maximum scatter/gather segments per request (header + segment blocks).
*/
-#define BLKIF_MAX_SEGMENTS_PER_REQUEST 255
+#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
/*
* NB. first_sect and last_sect in blkif_request_segment, as well as
@@ -512,22 +500,11 @@ struct blkif_request {
blkif_vdev_t handle; /* only for read/write requests */
uint64_t id; /* private guest value, echoed in resp */
blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */
- blkif_request_segment_t seg[BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK];
+ blkif_request_segment_t seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
};
typedef struct blkif_request blkif_request_t;
/*
- * A segment block is a ring request structure that contains only
- * segment data.
- *
- * sizeof(struct blkif_segment_block) <= sizeof(struct blkif_request)
- */
-struct blkif_segment_block {
- blkif_request_segment_t seg[BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK];
-};
-typedef struct blkif_segment_block blkif_segment_block_t;
-
-/*
* Cast to this structure when blkif_request.operation == BLKIF_OP_DISCARD
* sizeof(struct blkif_request_discard) <= sizeof(struct blkif_request)
*/
@@ -564,21 +541,6 @@ typedef struct blkif_response blkif_response_t;
*/
DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);
-/*
- * Index to, and treat as a segment block, an entry in the ring.
- */
-#define BLKRING_GET_SEG_BLOCK(_r, _idx) \
- (((blkif_segment_block_t *)RING_GET_REQUEST(_r, _idx))->seg)
-
-/*
- * The number of ring request blocks required to handle an I/O
- * request containing _segs segments.
- */
-#define BLKIF_SEGS_TO_BLOCKS(_segs) \
- ((((_segs - BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK) \
- + (BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK - 1)) \
- / BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK) + /*header_block*/1)
-
#define VDISK_CDROM 0x1
#define VDISK_REMOVABLE 0x2
#define VDISK_READONLY 0x4